Priority Queue Interface:
- Keep track of many items, quickly find the most important one.
- Order items by key(like Set interface)
- Usually optimized for max
- Focus on insert and delete_max operations(build can repeatedly insert)
class Priority_Queue(A):
def __init__(self, A):
self.A = []
def insert(self, x):
self.A.append(x)
def delete_max(self, A):
if len(self.A) < 1:
raise IndexError('pop from the empty array')
self.A.pop()
def sort(Queue, A):
pq = Queue()
for x in A:
pq.insert(x)
out = [pq.delete_max() for x in A]
out.reverse()
return out
Priority Queue Sort:
-
Priority queue translates into sorting algorithm
- build(A) by insort items one by one
- Repeatedlt delete_min to determine sorted order
-
Priority Queue: Array
- store items in an unsorted dynamic array
- insert(x) : append x to the end of the array
- delete_max : find max item in O(n) time the swap it to the end of the array,and remove it
Insert is quick,delete_max is slow
class PQ_Array(Priority_Queue):
def delete_max(self):
# find the max item in the array
n, A = len(self.A), self.A
m = 0
for i in range(1, n):
if A[i] > A[m]: m = i
A[m], A[n - 1] = A[n - 1], A[m]
return super.delete_max()
Priority Queue : Sorted Array
- store items in an sorted array
- delete_max() : delete the last one in the array
- insert(x) : append x to the array, then swap down to the sorted position in O(n) time
Delete_max is fast,but insert is low
class PQ_SortedArray(Priority_Queue):
def insert(self, x):
# maintain the order of the new array
super().insert(x)
i, A = len(A) - 1, self.A
while i > 0 and (A[i].key < A[i - 1].key):
A[i], A[i - 1] = A[i - 1], A[i]
i -= 1
Array as Completed Binary Tree:
Except largest layer,every layer has items.And all nodes are left_aligned.
Implicit Completed Tree:
Completed binary tree can be implicit instead of storing pointers.
def parent(i):
p = (i - 1) // 2
return p if i > 0 else i
def left(i):
l = 2 * i + 1
return l if l < n else i
def right(i):
r = 2 * i + 2
return r if l < n else i
def max_heapify_up(A, n, c):
p = parent(i)
if A[p].key < A[c].key:
A[p], A[c] = A[c], A[p]
return max_heapify_up(A, n, p)
def max_heapify_down(A, n, p):
l, r = left(i), right(i)
c = l if A[l].key > A[r].key else r
if A[c].key > A[p].key:
A[p], A[c] = A[c], A[p]
return max_heapify_down(A, n, c)
Binary heap:
- Idea:: keep larger items higher in the tree,only locally
- Property: Q[i] ≥ Q[j] for j ∈ {left(i),right(i)}
- Claim: for all nodes j in subtree(i)
Heap Insert:
- append the new item in the end of the array
- swap it with Max-Heap property
- if swap them,then recurve it untill the correct order
class PQ_Heap(Priority_Queue):
def insert(self, x):
super().insert(x)
n, A = self.n, self.A
max_heapify_up(A, n, n - 1)
Heap Delete_max:
- Can only easily delete the last one in the array,and the max item is at the root
- swap the item at root node (i==0) with the node
- max_heapify_down(i): swap root with it's larger child recursively
class PQ_Heap(Priority_Queue):
def delete_max(self):
n, A = self.n, self.A
A[n - 1], A[0] = A[0], A[n - 1]
max_heapify_down(A, n, 0)
return super().delete_max()