我正在python 3.7中使用heapq
我有两个关于heapq的问题:
如果我只想修改min元素,我不知道如何有效地保持堆不变。
这是我的实现。 (很慢)
q= [5,8,9,10]
heapq.heapify(q)
q[0] = 1200
heapq.heapify(q)
_siftdown()和_siftup()这两个方法有什么用?它们之间有什么区别?如何使用这两种方法来保持堆不变性?
最后,我使用_siftdown()实现代码(但是我仍然对这两种方法感到困惑,并且不能确保我的代码是否正确。)
s = time.time()
q = []
for i in range(0, 10000):
heapq.heappush(q, i)
for i in range(0, 10000):
q[0] = 10000+i
heapq._siftup(q,0)
print(q[0])
e2 =time.time()
print(e2-s)
s = time.time()
q = []
for i in range(0, 10000):
heapq.heappush(q, i)
for i in range(0, 10000):
q[0] = 10000+i
heapq.heapify(q)
print(q[0])
e2 =time.time()
print(e2-s)
输出为:
10000
0.09700560569763184
10000
7.193411350250244
答案 0 :(得分:1)
使用heapq.heapreplace
。最小的项始终位于q[0]
,因此,如有需要,对其进行修改,然后调用:
heapq.heapreplace(q, q[0])
我运行了您的时间并将其改写以提高速度:
import time
import heapq
s = time.time()
q = list(range(0, 10000))
heapq.heapify(q)
for i in range(0, 10000):
heapq.heapreplace(q, 10000+i)
print(q[0])
e2 = time.time()
print(e2 - s)
s = time.time()
q = list(range(0, 10000))
heapq.heapify(q)
for i in range(0, 10000):
q[0] = 10000+i
heapq._siftup(q, 0)
print(q[0])
e2 = time.time()
print(e2 - s)
产生:
10000
0.006845951080322266
10000
0.06091189384460449
创建列表然后调用heapify
然后使用heappush
更快。
heapq.heapreplace
比heapq._siftup
快,因为heapreplace
使用C模块用于heapq
,其中_siftup
在Python中。 _siftup
和_siftdown
仅出现在heapq.py
中,而不出现在_heapq
模块中
请勿致电_siftup
或_siftdown
。它们是heapq
的Python实现的内部。
我使用Python 3.2.3对此进行了测试