[英]Why heappop time complexity is O(logn) (not O(n)) in python?
For a list, the heappop will pop out the front element. 对于列表,heappop将弹出前面的元素。 Remove an element from the front of a list has time complexity O(n).
从列表前面删除元素的时间复杂度为O(n)。 Do I miss anything?
我想念什么吗?
A heappop() rearranges log(n)
elements in the list so that it doesn't have to shift every element. 一个heappop()重新排列列表中的
log(n)
元素,这样它就不必移动每个元素。
This is easy to see: 这很容易看出:
>>> from random import randrange
>>> from heapq import heapify, heappop
>>> h = [randrange(1000) for i in range(15)]
>>> heapify(h)
>>> h
[80, 126, 248, 336, 335, 413, 595, 405, 470, 592, 540, 566, 484, 970, 963]
>>> heappop(h)
80
>>> h
[126, 335, 248, 336, 540, 413, 595, 405, 470, 592, 963, 566, 484, 970]
>>> # ^----^---------^----^----^----^----^---------^----^----^--- elements that didn't move
Note that the popping operation didn't move most of the elements (for example 248 is in the same position before and after the heappop). 请注意,弹出操作没有移动大多数元素(例如248在heappop之前和之后处于相同位置)。
Heap pop is indeed O(logn)
complexity. 堆pop确实是
O(logn)
复杂性。
What you are missing is that pop from a heap is not like "removing the first element and left shift all elements by one". 你所缺少的是从堆中弹出是不是像“除去第一元素和左移一个所有要素”。 There is an algorithm to move element inside the list, after popping, there is no guarantee that the remaining elements in the list are in the same order as before.
有一个算法可以在列表中移动元素,弹出后,无法保证列表中的其余元素与之前的顺序相同。
The documentation is somewhat misleading if you're thinking about what list.pop
does. 如果您正在考虑
list.pop
作用,那么文档会有些误导。
If heap
is a minheap, then heap[0]
is indeed the smallest item. 如果
heap
是minheap,那么heap[0]
确实是最小的项目。 Python's list.pop
method returns the last element of the list, but heapq.heappop
returns the smallest (first!) element of the heap. Python的
list.pop
方法返回列表的最后一个元素,但heapq.heappop
返回堆的最小 (第一个!)元素。 However, it does this by popping off the last element of the heap (which is an O(1) operation on a list), swapping it with heap[0]
, bubbling it up (this is O(log n)), and then returning the value removed from heap[0]
to the caller. 但是,它通过弹出堆的最后一个元素(这是列表上的O(1)操作),使用
heap[0]
交换它,冒泡它(这是O(log n)),并且然后将从heap[0]
删除的值返回给调用者。
So: list.pop
returns the last item from a list and is O(1)
. 所以:
list.pop
返回列表中的最后一项,是O(1)
。 heapq.heappop
returns the first item to you, but not by shifting the entire array. heapq.heappop
返回第一个项目给你,但不是通过移动整个数组。
Take a look at the implementation of heapq.heappop: https://svn.python.org/projects/python/trunk/Lib/heapq.py 看一下heapq.heappop的实现: https ://svn.python.org/projects/python/trunk/Lib/heapq.py
It doesn't remove an element from the front of the list, it just returns it and replaces it with something else which takes O(logn), and reduces the length of the underlying list by removing the last element. 它不会从列表的前面删除一个元素,它只返回它并用其它需要O(logn)的东西替换它,并通过删除最后一个元素来减少底层列表的长度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.