3

我正在尝试使用 heapq 模块( https://docs.python.org/3/library/heapq.html )中的 Python(2.0)内置最小堆数据结构来构建最大堆。为此,我只需使用需要推入堆中的数字的负数。

使用这个(最大堆版本):

import heapq
h=[]
for i in xrange(10):
    heapq.heappush(h,-i)
    print h

我得到一些看起来不正确的东西:

[0]
[-1, 0]
[-2, 0, -1]
[-3, -2, -1, 0]
[-4, -3, -1, 0, -2]
[-5, -3, -4, 0, -2, -1]
[-6, -3, -5, 0, -2, -1, -4]
[-7, -6, -5, -3, -2, -1, -4, 0]
[-8, -7, -5, -6, -2, -1, -4, 0, -3]
[-9, -8, -5, -6, -7, -1, -4, 0, -3, -2]

最小堆版本看起来不错:

import heapq
h=[]
for i in xrange(10):
    heapq.heappush(h,i)
    print h

如你看到的:

[0]
[0, 1]
[0, 1, 2]
[0, 1, 2, 3]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3, 4, 5, 6, 7, 8]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

我错过了什么?

我检查了其他 SE 问题/答案(例如,python topN 最大堆、使用 heapq 还是自我实现?我在 Python 中使用什么来实现最大堆?等)但他们没有提到这个问题。

4

2 回答 2

4

正如@user2357112 已经提到的,它是一个最小堆。输出没有问题。两个输入之间的区别在于,在第一个场景中,您以排序方式输入数据,而在第二个场景中,您以反向排序方式输入数据。

min-heap 属性:每个节点的值大于或等于其父节点的值,最小值元素位于根节点。

案例 1:反向排序输入 = 10,9,8,7,6

         10
        [10]

         9
        /
      10
      [9,10]


        8
       / \
     10   9
     [8,10,9]


        7
       / \
      8   9
     /
    10
    [7, 8,9,10]

        6
       / \
      7   9
     / \
    10  8
    [6,7,9,10,8]

案例 2:排序输入 = 1,2,3,4,5

         1
        [1]

         1
        /
       2
      [1,2]


        1
       / \
      2   3
     [1,2,3]


        1
       / \
      2   3
     /
    4
    [1,2,3,4]

        1
       / \
      2   3
     / \
    4   5
    [1,2,3,4,5]

如果您对堆的构建方式以及每次输入后的平衡方式感兴趣,请访问以下 url。您可以一次插入一个元素并查看它的实际效果。 https://www.cs.usfca.edu/~galles/JavascriptVisual/Heap.html

于 2017-08-02T17:52:33.587 回答
2

最小堆的不变性是每个节点都小于它的任何一个子节点;两个孩子之间没有隐含的排序(因此,给定的一组值可以有许多有效的排序;唯一具有绝对固定位置的值是最小的,位于树的根部)。请注意,您的输出也是如此:

                  ,------------------,
  ,---+---,   ,---|----------+---,   |
  |   V   V   |   |          V   V   V
[-9, -8, -5, -6, -7, -1, -4, 0, -3, -2]
      |   |   ^   ^   ^   ^
      `---|---+---'   |   |
          `-----------+---'

您的另一个示例最终以完全排序的顺序结束的事实仅仅是一个巧合,基于将项目插入堆的不同顺序。

于 2017-08-02T17:47:58.113 回答