# Lecture 016 - Heaps and Priority Queue

We have defined the following functions for priority queue:

empty : T
singleton : S -> T
findMin : T -> (S union {T})
insert : T x S -> T
deleteMin : T -> T x (S union {T})
meld : T x T -> T
fromSeq : S seq -> T


where meld merge two priority queues.

Priority can be used for sequential $\log n$ heap sort. And other problems: - Huffman codes - clustering algorithms - event simulation - kinetic algorithms for motion simulation - you can use a max and a min heap for building "medium queue" (with quick select)

## Implementing Priority Queues

• deleteMin $O(1)$, insert $\Omega(n)$

• deleteMin $\Omega(n)$, insert $O(1)$

Balanced Tree: deleteMin (delete left-most), insert both $O(\log n)$. meld $O(n)$.

Heaps: unlike search tree, heap only maintain partial order (min heap small on root, max heap big on root)

• leftist heaps

• binomial heaps

• pairing heaps

• Fibonacci heaps

Binary Heap:

• shape property: all levels have 2 leafs except for last level

• heap property: parents are bigger/smaller than children

• Calculation: heap can be implemented using sequence

• left i = 2i + 1
• right i = 2i + 2
• parent i = ceil(i/2)-1
• (out of range means no such element)
• Implementation

• insertion: add new key to end of sequence, and swap up
• deletion: removing root, replace and swap children down
• Bound: same as balanced BST but faster in practice when maximum size is known (otherwise need dynamically sized array)

Note that Leftist Heap is better than all heaps listed here.

## Leftist Heaps

Leftist Heap: does not maintain BST property

• meld: basic operation of all other operations

• deleteMin: delete root and meld two subtree

• insert: meld with singleton

• fromSeq: fromSeq S = Seq.reduce Q.meld Q.empty (Seq.map Q.singleton S) ($O(n)$ work $O(\log^2 n)$ span)

Naive Meld: when meld two trees, choose choose right spine of smaller tree to insert bigger tree. (assuming min-heap, smaller tree is a tree with smaller key on root) $O(m+n)$ work since resulting tree is imbalanced.

Leftist Meld: add another field called rank on each node, denoting the number of nodes you would traverse to reach the end if you always go right.

• formal construction: $rank(Leaf) = 0$, $rank(node(\_, \_, R)) = 1 + rank(R)$

• leftist property: for every node $x$ in the heap, $rank(L(x)) \geq rank(R(x))$. Note that this may still cause tree to be unbalanced toward the left. But this is fine since we always meld-insert on the right.

Complete heap always Leftist.

makeLeftistNode() piles larger right-rank tree on the left

Leftist Rank Lemma: rank of the root node is at most $\log_2 (n+1)$.

To prove this. notice the smallest (in terms of the number of nodes) rank-0 heap has $0$ node, and rank-1 heap has $1$ node, rank-2 heap has $1 + 1 + 1 = 3$ nodes (by the leftist property, the rank of the left child of $x$ must be at least the rank of the right child of $x$), rank-3 heap has $1 + 3 + 3$ nodes. In general, let $n(r)$ denotes the number of nodes of a smallest heap with rank $r$, then if $x$ is the root of smallest heap with rank $r$: $n(r) = 1 + n(rank(L(x))) + n(rank(R(x)))$. Solving the recurrence gives smallest heap with rank $r$ must contain at least $2^r - 1$ nodes.

Leftist Work: makeLeftistNode() guarantees leftist property. Since meld only traverse right spines of $A$, $B$ and both trees are leftist, we have $W = O(\log m = \log n)$.

Table of Content