1. python heapq是一个最小堆,堆顶元素为最小值,最小(大)堆的逻辑结构是一颗二叉树,其中父节点的小(大于)于左右子节点,物理结构为一个数组。
heapq模块支持heappush(入堆)、heappop(出堆)、heapify(创建堆)等操作,详细请参考python官方文档(https://docs.python.org/2/library/heapq.html)。
2. 利用heapq实现prim算法
prim算法是指在一个加权连通图中寻找一颗最小子树,使得该连通子树权重和最小。
from collections import defaultdict
from heapq import heapify, heappop, heappush
def prim( nodes, edges ):
conn = defaultdict( list )
for n1,n2,c in edges:
conn[ n1 ].append( (c, n1, n2) )
conn[ n2 ].append( (c, n2, n1) )
mst = []
used = set( nodes[ 0 ] )
usable_edges = conn[ nodes[0] ][:]
heapify( usable_edges )
while usable_edges:
cost, n1, n2 = heappop( usable_edges )
if n2 not in used:
used.add( n2 )
mst.append( ( n1, n2, cost ) )
for e in conn[ n2 ]:
if e[ 2 ] not in used:
heappush( usable_edges, e )
return mst
nodes = list("ABCDEFG")
edges = [ ("A", "B", 7), ("A", "D", 5),
("B", "C", 8), ("B", "D", 9),
("B", "E", 7), ("C", "E", 5),
("D", "E", 15), ("D", "F", 6),
("E", "F", 8), ("E", "G", 9),
("F", "G", 11)]
print "prim:", prim( nodes, edges )
3. 利用heapq实现优先级队列
import heapq
class Item:
def __init__(self, name):
self.name = name
def __repr__(self):
return 'Item({!r})'.format(self.name)
class PriorityQueue:
def __init__(self):
self._queue = []
self._index = 0
def push(self, item, priority):
heapq.heappush(self._queue, (-priority, self._index, item))
self._index += 1
def pop(self):
return heapq.heappop(self._queue)[-1]
def __repr__(self):
print __repr__(self._queue)
q = PriorityQueue()
q.push(Item('foo'), 1)
q.push(Item('bar'), 5)
q.push(Item('spam'), 4)
print q.pop() # Item('bar')