python 中的堆顺序
heap order in python
堆数据结构的新内容。
正在尝试从列表创建堆。
li = [5, 7, 9, 1, 3]
heapq.heapify(li)
heapity之后,输出为
[1, 3, 9, 7, 5]
为什么是这个顺序?
我认为对于最小优先级堆,元素应该从最小到最大排序,即
heapq.heapify(li)
应与 li.sort()
相同
谁能帮我理解一下?
将堆看成树更容易:
1
3 9
7 5
其中每个节点都小于其任一子节点,但子节点的顺序无关紧要(这将堆与二叉搜索树区分开来)。
一棵完整的树通过按广度优先顺序对节点进行编号,从根作为节点 1 开始,允许在数组中进行简单的嵌入。
1(1)
3(2) 9(3)
7(4) 5(5)
有了这样的嵌入,以下关系成立:
li[i] <= li[2*i]
li[i] <= li[2*i + 1]
2*i
和2*i + 1
分别是计算位置i
:
节点左右子节点的公式
+--+--+
| v v
[1, 3, 9, 7, 5]
| ^ ^
+-----+--+
(您可以为从 0 开始的数组指定这些属性,但考虑从 1 开始的数组更简单。)
这样的列表是堆排序(比排序弱,因为所有排序的列表也是堆排序的) ,并允许有效地实现标准堆方法。
实际上,堆的排序方式与列表的排序方式不同。 Python 没有唯一的堆数据结构,并且使用带有堆操作的列表,这可能是你们中一些人混淆的根源。已排序(最低优先级)堆是满足 "heap condition" 的堆,因此任何 child 节点都大于其 parent。这并不意味着扁平化的表示是有序的。
您的示例在展平之前看起来像这样:
1
/ \
3 9
/ \
7 5
每个节点最多 2 children,children 总是从左到右添加,直到行满为止。然后通过连接行来创建平面表示:[1] + [3, 9] + [7, 5]
实际上堆排序是一种Half-arranged算法。主要思想是每个 parent 应该小于或等于它的 children(在最小堆排序中)。
所以我们知道第一个元素是最小的。当我们弹出堆的第一个元素时,下一个最小的元素将取而代之。
有关更多信息,请参阅以下链接:
堆数据结构的新内容。
正在尝试从列表创建堆。
li = [5, 7, 9, 1, 3]
heapq.heapify(li)
heapity之后,输出为
[1, 3, 9, 7, 5]
为什么是这个顺序?
我认为对于最小优先级堆,元素应该从最小到最大排序,即
heapq.heapify(li)
应与 li.sort()
谁能帮我理解一下?
将堆看成树更容易:
1
3 9
7 5
其中每个节点都小于其任一子节点,但子节点的顺序无关紧要(这将堆与二叉搜索树区分开来)。
一棵完整的树通过按广度优先顺序对节点进行编号,从根作为节点 1 开始,允许在数组中进行简单的嵌入。
1(1)
3(2) 9(3)
7(4) 5(5)
有了这样的嵌入,以下关系成立:
li[i] <= li[2*i]
li[i] <= li[2*i + 1]
2*i
和2*i + 1
分别是计算位置i
:
+--+--+
| v v
[1, 3, 9, 7, 5]
| ^ ^
+-----+--+
(您可以为从 0 开始的数组指定这些属性,但考虑从 1 开始的数组更简单。)
这样的列表是堆排序(比排序弱,因为所有排序的列表也是堆排序的) ,并允许有效地实现标准堆方法。
实际上,堆的排序方式与列表的排序方式不同。 Python 没有唯一的堆数据结构,并且使用带有堆操作的列表,这可能是你们中一些人混淆的根源。已排序(最低优先级)堆是满足 "heap condition" 的堆,因此任何 child 节点都大于其 parent。这并不意味着扁平化的表示是有序的。
您的示例在展平之前看起来像这样:
1
/ \
3 9
/ \
7 5
每个节点最多 2 children,children 总是从左到右添加,直到行满为止。然后通过连接行来创建平面表示:[1] + [3, 9] + [7, 5]
实际上堆排序是一种Half-arranged算法。主要思想是每个 parent 应该小于或等于它的 children(在最小堆排序中)。
所以我们知道第一个元素是最小的。当我们弹出堆的第一个元素时,下一个最小的元素将取而代之。
有关更多信息,请参阅以下链接: