Find Only The Smallest or Largest (Highest Priority)
Find Only The Smallest or Largest (Highest Priority)
1
Binary Heaps (a.k.a. Priority Queues)
• A binary heap is a binary tree that is:
– 1. Complete: the tree is completely filled except possibly the
bottom level, which is filled from left to right
– 2. Satisfies the heap property: The key stored in every node
is smaller than (or equal to) the keys stored in its children
• Therefore, the root node always contains the
smallest key in a heap
2 -2 1 • Which of
4
these is
6 1
0 2 6 not a
8 7
heap?
0 3 4 5
2
Array Implementation of Heaps
• Since heaps are complete binary trees, we can
avoid pointers and use an array as follows:
1
H: -- 2 4 6 7 2
6
2 3
0 1 2 3 4 5 6 7 4 6
4 5
N=5
7 6
11 9 6 10
4
DeleteMin – First Try
• DeleteMin:
2
• Delete (and return) value at root node
• We now have a “Hole” at the root 4 3
• Need to fill the hole with another value
7 5 8 9
• Replace with smallest child?
• Try replacing 2 with smallest child and 11 9 6 10
that node with its smallest child, and so
on…what happens? After DeleteMin
-- 2 4 3 7 5 8 9 11 9 6 10
6
DeleteMin – Heapify
10 3 3
4 3 4 10 4 8
7 5 8 9 7 5 8 9 7 5 10 9
11 9 6 11 9 6 11 9 6
7
Running Time Analysis of DeleteMin
• Running time is O(height of tree)
• What is the height of a complete binary tree
of N nodes?
– O(log2(N))
8
DeleteMin(H, N)
DeleteMin(H, N) --- Returns the minimum key
if (N <= 0) return “error”; // Heap is empty. So return an error code!
minKey = H[1]; // Save minKey
H[1] = H[N]; // Move the last key to the root
N = N – 1; // Decrease the # of nodes in the heap
if (N <= 0) return minKey; // Empty heap after deletion?
node = 1; // Start from the root and push the key down.
while (1){
left = 2*node; // left child
right = 2*node+1; // right child
smallest = node; // Assume the current node has the smaller key
if (left <= N and H[left] < H[smallest]) smallest = left;
if (right <= N and H[right] < H[smallest]) smallest = right;
if (smallest == node) return minKey; // We are done
tmp = H[node]; H[node] = H[smallest]; H[smallest] = tmp; // Exchange
node = smallest; // Move one level down and repeat
} //end-while
9
Insertion into a Heap
2
4 3
7 5 8 9
11 9 6 N = 10
-- 2 4 3 7 5 8 9 11 9 6
10
Insertion to a Heap: Push the key up
2
4 3
7 5 8 9
11 9 6 1 N = 11
-- 2 4 3 7 5 8 9 11 9 6 1
4 3 4 3 2 3
7 5 8 9 7 1 8 9 7 4 8 9
11 9 6 1 11 9 6 5 11 9 6 5
12
InsertKey(H, N, key)
InsertKey(H, key, N) -- Assumes the array has enough
-- room to hold the key
N = N + 1; // Increase the # of nodes in the heap
H[N] = key; // Insert the key
node = N; // Start from the last node and push the key up.
while (1){
parent = node/2; // parent of the node
if (parent < 1) return; // Already at the root? then done.
if (H[parent] < H[node]) return; // Parent key is smaller? then done
tmp = H[node]; // Exchange keys with the parent
H[node] = H[parent];
H[parent] = tmp;
node = parent; // Move one level up and repeat
} //end-while
13
Insertion to a Heap: Using Sentinel
• Every iteration of Insert needs to test:
1. if it has reached the top node H[1]
2. if parent <= key
-
• Can avoid first test if H[0] contains a very
large negative value (denoted by - ) 2
• Then, test #2 always stops at top because
• - < key for all keys 4 3
- 2 4 3 7 5 8 9 11 9 6 10
14
Heap Space Analysis
• Consider a heap of N nodes
• Space needed: O(N)
– Actually, O(MaxSize) where MaxSize = size of the
array
– One more variable to store the current size N
– With sentinel
• Array-based implementation uses total N+2 space
• Pointer-based implementation:
– pointers for children and parent
– Space for the key
– Total space =N*(Space for one key) + 3N + 1 (3 pointers per
node + 1 for size)
15
Heap Ops Running Time Analysis
• Consider a heap of N nodes
• FindMin: O(1) time
• DeleteMin and Insert: O(log N) time
• BuildHeap from N inputs: What is the running
time?
– Start with an empty heap
– Insert each element
• N Insert operations = O(N log N).
• Can we do better?
16
Building a Heap Bottom Up
• Treat input array as a heap and fix it using
Heapify
• for i = N/2 to 1 do
– Heapify(i) // Push the parent key down if
// necessary
• Why N/2?
– Nodes after N/2 are leaves!
17
Building a Heap Bottom Up: Example
1
20 20 20
2 3
6 3 3 3
6 6
4 5 6 7
10 16 2 10 10 7 2 10 8 7 2 10
14 8 7 14 8 14 10 16
16
8 9 10
2 2 20 20
6 3 6 20 6 2 6 2
8 7 20 10 8 7 3 10 8 7 3 10 8 7 3 10
14 10 16 14 10 16 14 10 16 14 10 16
18
One more Operation: DecreaseKey
• DecreaseKey(H, P,Delta, N): Decrease the
key value of node at position P by a positive 2
amount “Delta” within heap H with N nodes
4 3
• E.g. System administrators can increase 1
priority of important jobs.
7 5 8 9
• How?
• First, subtract “Delta” from current 11 9 6 10
value at P
• Heap property may be violated After DecreaseKey(H, 4, 6)
• Push the new key up or down? UP
• Running time: O(log2N) 1
2 3
4 5 8 9
11 9 6 10
19
One more Operation: IncreaseKey
• IncreaseKey(H, P,Delta, N): Increase the
key value of node at position P by a positive 2
10
amount “Delta” within heap H with N nodes
4 3
• E.g. Schedulers in OS often decrease
priority of CPU hogging jobs
7 5 8 9
• How?
• First, add “Delta” to current value at P 11 9 6 10
• Heap property may be violated
• Push the new key up or down? DOWN After IncreaseKey(H, 2, 6)
5 3
7 6 8 9
11 9 10 10
20
One more Operation: DeleteKey
• DeleteKey(H, P, N): Delete the node at
position P within heap H with N nodes 2
-
• E.g. Delete a job waiting in queue that
4 3
has been preemptively terminated by
user (you pressed Ctrl-C)
5 6 8 9
• How? 11 9 7 10
22
Summary of Heaps (Priority Queues)
• Complete binary trees satisfying the heap property
• Common implementation is a Binary Heap in an array
• FindMin is O(1)
• Insert and DeleteMin are O(log N)
• Merging is inefficient for binary heaps (O(N) time)
• Pointer-based alternatives such as Binomial Heaps
allow merging in O(log N) time – Not covered in class
23
Using a Heap for Sorting
• Main Idea: 8 9
Build Max-Heap
• Build a max-heap
2 9 5 8
• Do N DeleteMax
operations and store 4 5 4 2
each Max element in
the unused end of array DeleteMax
DeleteMax
25