优先级队列
在之前写最短路径,和哈夫曼编码的时候都用到了优先级队列优化,用的是c++中的包,priority_Queue。
那在Python中会以什么形式存在呢。
class Array(object):
def __init__(self, maxsize=None):
self.elem = [None] * maxsize
self.length = maxsize
def __setitem__(self, key, value):
self.elem[key] = value
def __len__(self):
return self.length
def __getitem__(self, item):
return self.elem[item]
def __iter__(self):
for i in self.elem:
yield i
class Maxheap(object):
def __init__(self, maxsize=None):
self.maxsize = maxsize
self.elem = Array(maxsize)
self.count = 0
def __len__(self):
return self.count
def add(self, value):
if self.count >= self.maxsize:
raise Exception('full')
self.elem[self.count] = value
self.count += 1
self.siftup(self.count - 1)
def siftup(self, ndx):
index = ndx
while index > 0:
parent = (index - 1) // 2
if self.elem[parent] < self.elem[index]:
self.elem[parent], self.elem[index] = self.elem[index], self.elem[parent]
index = parent
def extract(self):
if self.count <= 0:
raise Exception("empty")
value = self.elem[0]
self.count -= 1
self.elem[0] = self.elem[self.count]
self.siftdown(0)
return value
def siftdown(self, ndx):
parent = ndx
while parent * 2 + 1 < self.count:
child = parent * 2 + 1
if child != self.count - 1 and self.elem[child] < self.elem[child + 1]:
child = child + 1
if self.elem[parent] > self.elem[child]:
break
else:
self.elem[parent], self.elem[child] = self.elem[child], self.elem[parent]
parent = child
class PriorityQueue(object):
def __init__(self, maxsize):
self.maxsize = maxsize
self.maxheap = Maxheap(maxsize)
def push(self, priority, value):
# 注意这里把这个tuple push进去,python比较tuple从第一个开始比较这样就很巧妙的实现了按照优先级排序
entry = (priority, value)
self.maxheap.add(entry)
def pop(self, with_priority=False):
entry = self.maxheap.extract()
if with_priority:
return entry
else:
return entry[1]
def is_empty(self):
return len(self.maxheap) == 0
def test_priority_queue():
size = 5
pq = PriorityQueue(size)
pq.push(5, 'purple')
pq.push(0, 'white')
pq.push(3, 'orange')
pq.push(1, 'black')
res = []
while not pq.is_empty():
res.append(pq.pop())
assert res == ['purple', 'orange', 'black', 'white']
test_priority_queue()
按最小优先级出队的顺序的优先级队列:
import heapq
class PriorityQueue(object):
def __init__(self, maxsize):
self.maxsize = maxsize
self.minheap = []
def push(self, priority, value):
entry = (priority, value)
heapq.heappush(self.minheap, entry)
def pop(self, with_priority = False):
entry = heapq.heappop(self.minheap)
if with_priority:
return entry
else:
return entry[1]
def is_empty(self):
return len(self.minheap) == 0
def test_priority_queue():
size = 5
pq = PriorityQueue(size)
pq.push(5, 'purple') # priority, value
pq.push(0, 'white')
pq.push(3, 'orange')
pq.push(1, 'black')
res = []
while not pq.is_empty():
res.append(pq.pop())
print(res)
test_priority_queue()