我正在阅读heapq
模块的源代码,因为我在question上浏览了CodeReview,但我听不懂。
在关于堆的wikipedia article中,它说:
筛选:根据需要在树中上移节点;用于在插入后恢复堆条件。之所以称为“筛选”,是因为节点向上移动直到树达到正确的水平为止,就像在筛子中一样。
下移:类似于上移,在树中向下移动节点;用于删除或替换后恢复堆状态。
但是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
模块中的错误?还是我的理解不对?
答案 0 :(得分:2)
如评论中所述,这是一个命名问题。最常见的术语将根称为树的“顶部”,而其他级别的节点则位于根的“下方”。我们以该方向绘制树。那就是:
[1, 2, 3, 4, 5, 6]
[2, 3, 4, 5, 6, 1]
[3, 4, 5, 6, 1, 2]
[4, 5, 6, 1, 2, 3]
[5, 6, 1, 2, 3, 4]
[6, 1, 2, 3, 4, 5]
那么,说将项目从根目录移到较低级别是“向下筛选”。
您可以像有人在评论中所做的那样,提出论点,即将某物移至较低级别将增加其在后备数组中的索引,因此将其称为“筛选”是有意义的。但是人们正在可视化树模型,而不是数组实现。说到模型时,您的术语应与模型一致。
1
2 3
4 5 6 7
的作者决定使用非标准术语,总是让我感到烦恼。有人可能会说他在谈论实施问题,但我对此表示怀疑。注释中说:“提速:在树中向上移动节点……”显然,他指的是树模型。
维基百科https://en.wikipedia.org/wiki/Tree_structure说:
树形结构或树形图是一种以图形形式表示结构的分层性质的方法。之所以将其命名为“树结构”,是因为经典表示类似于树,即使图表与实际树相比通常是倒置的,“根”位于顶部,“叶”位于底部。
这个话题在早期就被讨论死了,也许是唐纳德·克努斯在《计算机编程的艺术》中最著名的。参见https://www.quora.com/Why-are-trees-in-computer-science-generally-drawn-upside-down-from-how-trees-are-in-real-life。