二叉堆是实现堆排序及优先队列的基础/
队列的特点是先进先出(FIFO)
入队列,将新元素置于队尾
出队列,对头元素最先被移出
而优先队列不再遵循先入先出的原则,而是分为两种情况:
最大优先队列,无论入队顺序如何,都是当前最大的元素优先出队
最小优先队列,无论入队顺序如何,都是当前最小的元素优先出队
二叉堆的特性
最大堆的堆顶是整个堆中的最大元素
最小堆的堆顶是整个堆中的最小元素
因此可以用最大堆来实现最大优先队列,这样的话,每一次入队操作就是堆的插入操作,每一次出对操作就是删除堆顶节点。
代码实现(这我也看不懂)
class PriorityQueue:
def __init__(self):
self.array = []
self.size = 0
def enqueue(self, element):
self.array.append(element)
self.size += 1
self.up_adjust()
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):
child_index = self.size - 1
parent_index = (child_index - 1) // 2
# temp保存插入的叶子节点值,用于最后的赋值
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):
parent_index = 0
# temp保存父节点值,用于最后的赋值
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
queue = PriorityQueue()
queue.enqueue(3)
queue.enqueue(5)
queue.enqueue(10)
queue.enqueue(2)
queue.enqueue(7)
print(queue.dequeue())
print(queue.dequeue())