【发布时间】:2019-05-01 22:21:13
【问题描述】:
我正在阅读 heapq 模块源代码,因为我在 CodeReview 上查看了 question 并且我无法理解某些内容。
在wikipedia article about heap 中说:
sift-up:在树中向上移动一个节点,只要需要;用于在插入后恢复堆状态。之所以称为“筛选”,是因为节点在树上向上移动,直到达到正确的级别,就像在筛子中一样。
sift-down:在树中向下移动一个节点,类似于 sift-up;用于在删除或替换后恢复堆状态。
但是heappush(source code)的代码是:
def heappush(heap, item):
"""Push item onto heap, maintaining the heap invariant."""
heap.append(item)
_siftdown(heap, 0, len(heap)-1)
如果我没看错维基百科,在插入元素时,我希望看到的是 siftup 调用,而不是 siftdown 调用。
heappop (source here) 也是如此:
def heappop(heap):
"""Pop the smallest item off the heap, maintaining the heap invariant."""
lastelt = heap.pop() # raises appropriate IndexError if heap is empty
if heap:
returnitem = heap[0]
heap[0] = lastelt
_siftup(heap, 0)
return returnitem
return lastelt
从维基百科的文章中,我期待一个siftdown 的电话,但得到了一个siftup 的电话。
这是维基百科或heapq 模块中的错误吗?还是我的理解有误?
【问题讨论】:
-
在流行音乐之后需要筛选是有道理的。毕竟,您已删除了堆的顶部元素。必须有东西向上移动才能取代它的位置。
-
那么维基百科在这种情况下是错误的?
-
哦,我明白了:“筛选:用于在删除或替换后恢复堆状态”但
heappop()称之为_siftup()。在这种情况下,我认为维基百科的命名实际上更标准。 -
这只是与可视化有关。通常堆被想象为根在顶部,然后维基百科的语言是有意义的,但是没有理由不能想象堆在底部的根。我的意思是:现实生活中的树木扎根于土壤,而不是天空。 ;-)
-
@trincot 您认为正在筛选的内容也存在歧义。如果您从根处的元素(您在顶部可视化)开始并将其向下推,则必须将其其中一个子元素向上推。所以有些东西正在朝各个方向发展。
标签: python algorithm data-structures heap standard-library