python中的堆顺序

Posted

技术标签:

【中文标题】python中的堆顺序【英文标题】:heap order in python 【发布时间】:2018-11-10 14:31:53 【问题描述】:

堆数据结构的新功能。

试图从一个列表中创建一个堆。

li = [5, 7, 9, 1, 3]

heapq.heapify(li)

heapity之后的输出是

[1, 3, 9, 7, 5]

为什么是这个顺序? 我认为对于最小优先级堆,元素应该从 min 到 max 排序,即 heapq.heapify(li) 应该与 li.sort() 相同

谁能帮我理解一下?

【问题讨论】:

有多种方法可以将列表变成堆,请参阅here。 What is Python's heapq module?的可能重复 heapq 中的堆是一种二叉树。每个父母heap[k]heap[2*k+1]heap[2*k+2] 都有孩子。每个父母都小于或等于它的孩子。在熟悉 Python 实现之前,请通读 heap data structure。 【参考方案1】:

将堆视为树更容易:

         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*i2*i + 1分别是计算i位置节点左右子节点的公式:

 +--+--+
 |  v  v
[1, 3, 9, 7, 5]
    |     ^  ^
    +-----+--+

(您可以为基于 0 的数组指定这些属性,但考虑使用基于 1 的数组更简单。)

这样的列表是 heap-ordered(比 sorted 弱,因为所有排序的列表也是 heap-ordered),并且允许标准堆方法有效实施。

【讨论】:

这样的列表是堆排序的,这与排序不同——我还要注意,通常的排序意味着堆排序,但反之则不然。 【参考方案2】:

实际上堆排序是一种半排列算法。主要思想是每个父母都应该小于或等于它的孩子(在最小堆排序中)。 所以我们知道第一个元素是最小的。当我们弹出堆的第一个元素时,下一个最小的元素将取代它。 有关更多信息,请参阅以下点赞:

heap sort wikipedia

【讨论】:

【参考方案3】:

实际上,堆的排序方式与列表的排序方式不同。 Python 没有唯一的堆数据结构,并且使用带有堆操作的列表,这可能是你们中一些人混淆的根源。排序(最低优先级)堆是满足“堆条件”的堆,这样任何子节点都大于其父节点。这并不意味着展平的表示将是有序的。

您的示例在展平之前看起来像这样:

    1
   / \
  3   9
 / \
7   5

每个节点最多有 2 个子节点,子节点总是从左到右添加,直到行满。然后通过连接行来创建平面表示:[1] + [3, 9] + [7, 5]

【讨论】:

以上是关于python中的堆顺序的主要内容,如果未能解决你的问题,请参考以下文章

用 Javascript 中的堆算法解决排列问题

Java中的堆和栈的区别

Java中的堆和栈的区别

Java中的堆和栈的区别

数据结构堆、栈与程序内存的堆、栈怎么区别

Python:在优先队列实现中使用我的堆