优先队列
优先队列分为最大优先队列和最小优先队列。
最大优先队列:无论入队顺序如何,都是最大元素优先出队,基于最大堆实现。
最小优先队列:无论入队顺序如何,都是最小元素优先出队,基于最小堆实现。
二叉堆结点“上浮”和“下沉”的时间复杂度是 O ( l o g n ) O(logn) O(logn),所以优先队列入队和出队的时间复杂度也是 O ( l o g n ) O(logn) O(logn)。
# 最大优先队列
class PriorityQueue:
def __init__(self):
self.array = []
self.size = 0
def print(self):
print('当前元素:',self.array)
def enqueue(self,element):
self.array.append(element)
self.size += 1
self.up_adjust()
self.print()
def dequeue(self):
if self.size < 0:
raise Exception('队列为空!')
head = self.array[0]
self.array[0] = self.array[self.size-1]
self.size -= 1
self.down_adjust()
return head
def up_adjust(self):
'''
上浮,使得最大值浮到最上面
:return:
'''
child_index = len(self.array) - 1
parent_index = (child_index - 1) // 2
temp = self.array[child_index] # 保存插入叶子结点的值,用于最后赋值
while child_index > 0 and temp > self.array[parent_index]:
self.array[child_index] = self.array[parent_index]
child_index = parent_index
parent_index = (parent_index - 1) // 2
self.array[child_index] = temp
def down_adjust(self):
'''
下沉,小的值下沉,使最大值在最上面
:return:
'''
parent_index = 0
temp = self.array[parent_index]
child_index = 1
while child_index < self.size:
# 如果有右孩子,且右孩子的值大于左孩子的值,则定位到右孩子
if child_index + 1 < self.size and self.array[child_index + 1] > self.array[child_index]:
child_index += 1
# 如果父节点的值小于任何一个孩子的值,跳出
if temp >= self.array[child_index]:
break
self.array[parent_index] = self.array[child_index]
parent_index = child_index
child_index = 2 * child_index + 1
self.array[parent_index] = temp
if __name__ == '__main__':
queue = PriorityQueue()
queue.enqueue(3)
queue.enqueue(8)
queue.enqueue(4)
queue.enqueue(6)
queue.enqueue(10)
queue.enqueue(2)
print(queue.dequeue())
print(queue.dequeue())
print(queue.dequeue())
print(queue.dequeue())
参考:《漫画算法》