我在阅读heapq
模块源代码,因为我在question上查看了aCodeReview,我不能理解一些东西。
在关于堆的wikipedia article中,它说:
向上筛选:根据需要在树中向上移动一个节点;用于在插入后恢复堆状态。之所以称为“sift”,是因为节点向上移动树,直到达到正确的级别,如在筛子中。
向下筛选:在树中向下移动一个节点,类似于向上筛选;用于在删除或替换后恢复堆状态。
但是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
模块的错误?还是我的理解错了? 最佳答案
如评论所述,这是一个命名问题最常见的术语称根为树的“顶部”,而其他级别的节点则位于根的“下方”。我们按那个方向画这棵树即:
1
2 3
4 5 6 7
因此,可以说,将项目从根目录移动到较低的级别就是“向下筛选”。
你可以提出这样的论点,就像有人在评论中所做的那样,把某个东西移到一个较低的级别会增加它在备份数组中的索引,所以把它称为“筛选”是有意义的。但是人们是在可视化树模型,而不是数组实现当谈到模型时,您的术语应该与模型一致。
我一直觉得
heapq
的作者决定使用非标准术语有点烦人。有人可能会说他在讨论执行问题,但我对此表示怀疑评论说,“向上筛选:在树中向上移动一个节点…”显然,他指的是树模型。维基百科说:
树结构或树图是以图形形式表示结构层次性质的一种方法。它之所以被命名为“树结构”,是因为经典的表示法类似于树,尽管与实际的树相比,图表通常是颠倒的,顶部是“根”,底部是“叶”。
这一话题在早期就被讨论得无影无踪,也许最著名的是唐纳德·克努特在《计算机编程艺术》一书中所说的见https://en.wikipedia.org/wiki/Tree_structure。
关于python - Heapq模块实现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53546052/