簡體   English   中英

為什么heappop時間復雜度在python中是O(logn)(不是O(n))?

[英]Why heappop time complexity is O(logn) (not O(n)) in python?

對於列表,heappop將彈出前面的元素。 從列表前面刪除元素的時間復雜度為O(n)。 我想念什么嗎?

一個heappop()重新排列列表中的log(n)元素,這樣它就不必移動每個元素。

這很容易看出:

>>> 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

請注意,彈出操作沒有移動大多數元素(例如248在heappop之前和之后處於相同位置)。

堆pop確實是O(logn)復雜性。

你所缺少的是從堆中彈出是不是像“除去第一元素和左移一個所有要素”。 有一個算法可以在列表中移動元素,彈出后,無法保證列表中的其余元素與之前的順序相同。

如果您正在考慮list.pop作用,那么文檔會有些誤導。

如果heap是minheap,那么heap[0]確實是最小的項目。 Python的list.pop方法返回列表的最后一個元素,但heapq.heappop返回堆的最小 (第一個!)元素。 但是,它通過彈出堆的最后一個元素(這是列表上的O(1)操作),使用heap[0]交換它,冒泡它(這是O(log n)),並且然后將從heap[0]刪除的值返回給調用者。

所以: list.pop返回列表中的最后一項,是O(1) heapq.heappop返回第一個項目給你,但不是通過移動整個數組。

看一下heapq.heappop的實現: https ://svn.python.org/projects/python/trunk/Lib/heapq.py

它不會從列表的前面刪除一個元素,它只返回它並用其它需要O(logn)的東西替換它,並通過刪除最后一個元素來減少底層列表的長度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM