Heapq模块实现

时间:2018-11-29 19:15:09

标签: python algorithm data-structures heap standard-library

我正在阅读heapq模块的源代码,因为我在question上浏览了CodeReview,但我听不懂。

在关于堆的wikipedia article中,它说:

  

筛选:根据需要在树中上移节点;用于在插入后恢复堆条件。之所以称为“筛选”,是因为节点向上移动直到树达到正确的水平为止,就像在筛子中一样。

     

下移:类似于上移,在树中向下移动节点;用于删除或替换后恢复堆状态。

但是heappushsource code)的代码是:

def heappush(heap, item):
    """Push item onto heap, maintaining the heap invariant."""
    heap.append(item)
    _siftdown(heap, 0, len(heap)-1)

如果我没看错维基百科,那么在插入一个元素时,我期望看到一个siftup调用,而不是一个siftdown调用。

heappopsource 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 个答案:

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