以堆来实现优先级队列,堆其实是特殊的完全二叉树。堆中的每个父节点都是要大于等于或者小于等于它的孩子节点
列表与优先级队列
列表
列表中存储的元素是乱序的,插入的时间复杂度为1,取最值的时间复杂度为O(n)
列表中存储的元素是有序的,插入的时间复杂度为O(n),取最值的时间复杂度为1
优先级队列
- 优先级队列插入的时间复杂度为O(log(n)),取最值的时间复杂度为1
代码
class MaxHeap:
"""
最大堆:索引第一位优先级最高
"""
def __init__(self):
self.data = []
self.count = -1
def add(self, priority, value):
self.data.append((priority, value))
self.count += 1
self.siftup(self.count) # 向上堆排序
def extract(self):
if self.count == -1:
raise Exception("堆为空!")
elif self.count == 0:
self.count -= 1
return self.data[0]
else:
value = self.data[0]
self.data[0] = self.data[self.count] # 最右下节点值放到root
self.count -= 1
self.data.pop() # 删除最右下节点
self.siftdown(0) # 向下堆排序
return value
def siftup(self, index):
if index != 0:
parent = int((index - 1) / 2)
if self.data[index] > self.data[parent]:
self.data[index], self.data[parent] = self.data[parent], self.data[index]
self.siftup(parent)
def siftdown(self, index):
left = index * 2 + 1
right = index * 2 + 2
if left < len(self.data):
big = left
if right < len(self.data):
if self.data[left] < self.data[right]:
big = right
if self.data[index] < self.data[big]:
self.data[index], self.data[big] = self.data[big], self.data[index]
self.siftdown(big)
class PriorityQueue:
def __init__(self):
self._MaxHeap = MaxHeap()
def push(self, priority, value):
self._MaxHeap.add(priority, value)
def pop(self):
return self._MaxHeap.extract()
def test_priority_queue():
pq = PriorityQueue()
pq.push(10, 'a')
pq.push(6, 'b')
pq.push(7, 'c')
pq.push(3, 'd')
print(pq.pop())
print(pq.pop())
print(pq.pop())
print(pq.pop())
if __name__ == "__main__":
test_priority_queue()
文档信息
- 本文作者:Weikang Yu
- 本文链接:https://AccelYu.github.io/2020/05/17/tree_one/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)