Reputation: 538
import heapq
minHeap = [4, 7, 2, 8, 1, 3]
heapq.heapify(minHeap) # O(n log n) operation
print(minHeap) # [1, 4, 2, 8, 7, 3]
heapq.heappush(minHeap, 1) # O(log n) operation?
print(minHeap) # [1, 4, 1, 8, 7, 3, 2]
I guess heapq.heappush will create a new array and assigned to minHeap. If this is correct, wouldn't this operation be an O(n) operation instead of O(log n)?
Upvotes: 0
Views: 38
Reputation: 349946
I guess
heapq.heappush
will create a new array
No, it performs an append
to the given list. See the source code of CPython on github:
def heappush(heap, item):
"""Push item onto heap, maintaining the heap invariant."""
heap.append(item)
_siftdown(heap, 0, len(heap)-1)
That append
is followed by a _siftdown
call, which will check (and potentially update) that list to make sure it maintains the heap invariant. That process has a worst case complexity of O(log𝑛).
Here is the code for _siftdown
:
def _siftdown(heap, startpos, pos):
newitem = heap[pos]
# Follow the path to the root, moving parents down until finding a place
# newitem fits.
while pos > startpos:
parentpos = (pos - 1) >> 1
parent = heap[parentpos]
if newitem < parent:
heap[pos] = parent
pos = parentpos
continue
break
heap[pos] = newitem
Note how the >>
operator halves the index in each iteration, so that if break
never gets executed (which is the worst case), there are O(log𝑛) iterations of this loop.
The referenced file has extended comment blocks which explain the principle of a binary heap and how it is implemented. See also Wikipedia - Binary heap - insert.
Unrelated, but the comment in your code that claims that heapify
is a O(𝑛log𝑛) operation, is wrong. It is O(𝑛). See How can building a heap be O(n) time complexity?.
Upvotes: 3