了解如何在Python中创建堆

Sam*_*amy 24 python

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

我已经跟踪了该heapq.py文件,但是我很难理解如何创建/更新关于单词的堆.

因此,我认为理解它的最佳方法是弄清楚如何从头开始创建堆.

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

Hue*_*ido 35

在Python 2.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
Run Code Online (Sandbox Code Playgroud)

你可以找到更多关于堆函数:heappush, heappop, heappushpop, heapify, heapreplace堆python文档.


sla*_*tir 14

这是基于Sedgewick的另一种变体

堆在内部表示为数组,其中如果节点位于k,则它的子节点为2*k且2*k + 1.数组的第一个元素未使用,以使数学更方便.

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

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

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
Run Code Online (Sandbox Code Playgroud)

这是堆插入的可视化,插入字母表的前15个字母:[ao]

堆插入可视化


Jor*_*ley 13

这是在这里找到的代码的略微修改版本:http://code.activestate.com/recipes/577086-heap-sort/

def HeapSort(A,T):
    def heapify(A):
        start = (len(A) - 2) / 2
        while start >= 0:
            siftDown(A, start, len(A) - 1)
            start -= 1

    def siftDown(A, start, end):
        root = start
        while root * 2 + 1 <= end:
            child = root * 2 + 1
            if child + 1 <= end and T.count(A[child]) < T.count(A[child + 1]):
                child += 1
            if child <= end and T.count(A[root]) < T.count(A[child]):
                A[root], A[child] = A[child], A[root]
                root = child
            else:
                return

    heapify(A)
    end = len(A) - 1
    while end > 0:
        A[end], A[0] = A[0], A[end]
        siftDown(A, 0, end - 1)
        end -= 1


if __name__ == '__main__':
    text = "the quick brown fox jumped over the the quick brown quick log log"
    heap = list(set(text.split()))
    print heap

    HeapSort(heap,text)
    print heap
Run Code Online (Sandbox Code Playgroud)

产量

['brown', 'log', 'jumped', 'over', 'fox', 'quick', 'the']
['jumped', 'fox', 'over', 'brown', 'log', 'the', 'quick']
Run Code Online (Sandbox Code Playgroud)

你可以在这里看到这个程序 http://goo.gl/2a9Bh


Ame*_*ina 5

您的困惑可能来自以下事实:Python 模块heapq没有堆定义为具有自己的方法(例如 a或 a )的数据类型(类)。相反,它提供了可以在 Python 上运行的函数。dequelistlist

最好将其视为heapq一个模块,提供一组算法(方法)来将列表解释为堆并相应地操作它们。请注意,在内部将堆表示数组(作为抽象数据结构)是很常见的,并且 Python 已经具有用于此目的的列表,因此heapq仅提供将列表操作为堆的方法是有意义的。

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

>>> my_list = [2, -1, 4, 10, 0, -20]
Run Code Online (Sandbox Code Playgroud)

heapq要使用from创建堆,my_list我们只需要调用heapify它,它会简单地重新排列列表的元素以形成最小堆:

>>> import heapq
>>> # NOTE: This returns NoneType:
>>> heapq.heapify(my_list)
Run Code Online (Sandbox Code Playgroud)

请注意,您仍然可以访问堆下的列表,因为heapify所做的只是更改引用的my_list

>>> my_list
[-20, -1, 2, 10, 0, 4]
Run Code Online (Sandbox Code Playgroud)

从 持有的堆中弹出元素my_list

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