了解如何在Python中创建堆

了解如何在Python中创建堆,python,heap,Python,Heap,例如,Python中的collections.Count.most_common函数使用heapq模块返回文件中最常用单词的计数 我已经跟踪了heapq.py文件,但是我在理解堆是如何创建/更新的方面遇到了一些困难 所以,我认为对我来说理解它的最好方法是找出如何从头开始创建堆 有人能提供一个伪代码来创建一个表示字数的堆吗?这是这里代码的一个稍微修改的版本: 您可以在此处可视化该程序 在Python2.X和3.X中,通过可导入库heapq支持堆。它提供了许多函数来处理Python列表中建模的堆数据

例如,Python中的
collections.Count.most_common
函数使用
heapq
模块返回文件中最常用单词的计数

我已经跟踪了
heapq.py
文件,但是我在理解堆是如何创建/更新的方面遇到了一些困难

所以,我认为对我来说理解它的最好方法是找出如何从头开始创建堆


有人能提供一个伪代码来创建一个表示字数的堆吗?

这是这里代码的一个稍微修改的版本:

您可以在此处可视化该程序

在Python2.X和3.X中,通过可导入库heapq支持堆。它提供了许多函数来处理Python列表中建模的堆数据结构。 例如:

>>> from heapq import heappush, heappop
>>> heap = []
>>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
>>> for item in data:
        heappush(heap, item)

>>> ordered = []
>>> while heap:
        ordered.append(heappop(heap))

>>> ordered
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> data.sort()
>>> data == ordered
True

您可以在中找到有关堆函数的更多信息:
heappush、heappop、heapushpop、heapify、heapreplace。

这里是基于

堆在数组内部表示,如果节点位于k,则其子节点位于2*k和2*k+1。不使用数组的第一个元素,以使计算更方便

要将新元素添加到堆中,可以将其附加到数组的末尾,然后重复调用swim,直到新元素在堆中找到它的位置

要删除根,请将其与数组中的最后一个元素交换,删除它,然后调用sink,直到交换的元素找到其位置

swim(k):
  while k > 1 and less(k/2, k):
    exch(k, k/2)
    k = k/2

sink(k):
  while 2*k <= N:
    j = 2*k
    if j < N and less(j, j+1):
      j++
    if not less(k, j):
      break
    exch(k, j)
    k = j
swim(k):
当k>1且小于1时(k/2,k):
行政会议(k,k/2)
k=k/2
水槽(k):

而2*k您的困惑可能来自这样一个事实,即Python模块没有将堆定义为数据类型(一个类),并使用它自己的方法(例如,在一个或一个
列表中
)。相反,它提供了可以在Python
列表上运行的函数

最好将
heapq
视为一个模块,提供一组算法(方法)来将列表解释为堆并相应地操作它们。请注意,它对于内部as(作为抽象数据结构)是通用的,Python已经有了用于此目的的列表,因此,
heapq
只提供将列表作为堆进行操作的方法是有意义的

让我们看一个例子。从一个简单的Python列表开始:

>>> my_list = [2, -1, 4, 10, 0, -20]
要从
my_list
创建具有
heapq
的堆,我们只需调用
heapify
,它只需重新排列列表的元素以形成最小堆:

>>> import heapq
>>> # NOTE: This returns NoneType:
>>> heapq.heapify(my_list)
请注意,您仍然可以访问堆下面的列表,因为所有的
heapify
操作都是更改:

my_list
持有的堆中弹出元素:

>>> [heapq.heappop(my_list) for x in range(len(my_list))]
[-20, -1, 0, 2, 4, 10]

您好,从@Hueston Rido的回答来看,从堆中推送和弹出似乎会自动对数据进行排序,这在您发布的堆排序代码中看起来非常简单。我肯定错过了一些东西。你能解释一下为什么你没有简单地从堆中推出来对数据进行排序吗?如果我们想可视化二叉树(一步一步的排序过程),在树的过程中,我们应该使用二叉树还是仅仅是一个列表。我的印象是OP不必使用内置的heapq…这太棒了!我只希望它能慢一点,或者有办法暂停/重新启动它。哦,很高兴你喜欢它!这只是一个动画gif。我是几年前做的——甚至不确定我是否还有代码!:)
>>> import heapq
>>> # NOTE: This returns NoneType:
>>> heapq.heapify(my_list)
>>> my_list
[-20, -1, 2, 10, 0, 4]
>>> [heapq.heappop(my_list) for x in range(len(my_list))]
[-20, -1, 0, 2, 4, 10]