例如,Python中的collections.Count.most_common
函数使用heapq
模块返回文件中最常用单词的计数。
我已经跟踪了heapq.py
文件,但是我在理解如何创建/更新关于单词的堆时遇到了一些麻烦。
因此,我认为理解它的最好方法是弄清楚如何从头开始创建堆。
有人可以提供伪代码来创建代表字数的堆吗?
答案 0 :(得分: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
您可以在heap python docs中找到有关堆功能的更多信息:heappush, heappop, heappushpop, heapify, heapreplace
。
答案 1 :(得分: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
这里是堆插入的可视化,插入字母的前15个字母:[a-o]
答案 2 :(得分:12)
这是稍微修改过的代码版本: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
输出
['brown', 'log', 'jumped', 'over', 'fox', 'quick', 'the']
['jumped', 'fox', 'over', 'brown', 'log', 'the', 'quick']
您可以在此处查看该程序 http://goo.gl/2a9Bh
答案 3 :(得分:2)
您的困惑可能是由于Python模块heapq
并没有不使用自己的方法将堆定义为数据 type (一个类) (例如,在deque
或list
中)。相反,它提供了可以在Python list
上运行的功能。
最好将heapq
视为一个提供一组算法(方法)的模块,以将列表解释为堆并进行相应的操作。请注意,内部使用represent heaps作为arrays(作为抽象数据结构)是很常见的,并且Python已经具有满足该目的的列表,因此heapq
仅提供操作方法是有意义的列为堆。
让我们看一个例子。从一个简单的Python列表开始:
>>> my_list = [2, -1, 4, 10, 0, -20]
要使用heapq
中的my_list
创建一个堆,我们只需要调用heapify
即可,它只需重新排列列表的元素即可形成最小堆:
>>> import heapq
>>> # NOTE: This returns NoneType:
>>> heapq.heapify(my_list)
请注意,由于所有heapify
完成的操作都是更改value referenced by my_list
,因此您仍然可以访问堆下面的列表:
>>> my_list
[-20, -1, 2, 10, 0, 4]
从my_list
所拥有的堆中弹出元素:
>>> [heapq.heappop(my_list) for x in range(len(my_list))]
[-20, -1, 0, 2, 4, 10]