Lecture8 Heaps
Lecture8 Heaps
• Priority Queue property: for two elements in the queue, x and y, if x has a lower
priority value than y, x will be deleted before y
Applications of the Priority Q
• Hold jobs for a printer in order of length
• Store packets on network routers in order of urgency
• Simulate events
• Select symbols for compression
• Sort numbers
• Anything greedy
Naïve Priority Q Data Structures
• Unsorted list:
• insert:
• deleteMin:
• Sorted list:
• insert:
• deleteMin:
Binary Search Tree
Priority Q Data Structure
8
insert:
5 11
deleteMin:
2 6 10 12
4 7 9 14
13
Binary Heap
Priority Q Data Structure
Heap-order property
• parent’s key is less than children’s keys
• result: minimum is always at the top
2
Structure property
• complete tree: fringe nodes packed to the left
4 known
• result: depth is always O(log n); next open location always 5
7 6 10 8
11 9 15 14 13
How do we find the minimum?
Array Storage Trick 1
2
Calculations 2 3
• children: 4 5
• parent:
4 5 6 7
• root:
7 6 10 8
• next free:
11 9 15 14 13
8 9 10 11 12
0 1 2 3 4 5 6 7 8 9 10 11 12 13
13 2 4 5 7 6 10 8 11 9 15 14 13
pqueue.deleteMin() 2
2 ?
4 5 4 5
7 6 10 8 7 6 10 8
11 9 15 14 13 11 9 15 14 13
Percolate Down
? 13
4 5 4 5
7 6 10 8 7 6 10 8
11 9 15 14 13 11 9 15 14
4 4
13 5 6 5
7 6 10 8 13
7 10 8
11 9 15 14 11 9 15 14 Done!
typedef struct { int extractMin(MinHeap *heap) {
int arr[MAX_SIZE]; // Array to store heap elements if (heap->size == 0) {
int size; printf("Heap is empty!\n");
return -1;
} MinHeap;
}
int minElement = heap->arr[0];
void heapifyDown(MinHeap *heap, int pos) {
heap->arr[0] = heap->arr[heap->size - 1];
int left = leftChild(pos);
heap->size--;
int right = rightChild(pos);
heapifyDown(heap, 0);
int smallest = pos;
return minElement;
if (left < heap->size && heap->arr[left] < heap->arr[smallest])
}
smallest = left;
if (right < heap->size && heap->arr[right] < heap->arr[smallest])
smallest = right;
if (smallest != pos) {
swap(&heap->arr[pos], &heap->arr[smallest]); How much is the runtime costs?
heapifyDown(heap, smallest);
}
}
11
BinaryHeap::Insert
2 pqueue.insert(3) 2
4 5 4 5
7 6 10 8 7 6 10 8
11 9 12 14 20 11 9 12 14 20 ?
Percolate Up
2 2
4 5 4 5
3
7 6 10 8 7 6 ? 8
3
11 9 12 14 20 ? 11 9 12 14 20 10
2 2
3
4 ? 4 3
7 6 5 8 7 6 5 8
11 9 12 14 20 10 11 9 12 14 20 10
void heapifyUp(MinHeap *heap, int pos){ void insertMinHeap(MinHeap *heap, int value) {
if(pos==1 || heap->arr[parent(pos)] < heap->arr[pos]){ if (heap->size == MAX_SIZE) {
return; printf("Heap is full!\n");
swap(&heap->arr[parent(pos)], &heap->arr[pos]); return;
pos=parent(pos); }
heapifyUp(heap, pos); int i = heap->size;
} heap->arr[i] = value;
heap->size++;
heapifyUp(heap, i);
}
14
Performance of Binary Heap
Binary Binary AVL AVL tree
heap heap avg tree avg case
worst case worst
case case
Insert O(log n) O(1) O(log O(log n)
percolate n)
s ~1.6
levels
DeleteM O(log n) O(log n) O(log O(log n)
in n)
In practice: binary heaps much simpler to code, lower
constant factor overhead
Changing Priorities
In many applications the priority of an object in a priority queue may change over
time
• if a job has been sitting in the printer queue for a long time increase its priority
• unix “renice”
• Sysadmin may raise priority of a critical task
Must have some (separate) way to find the position in the queue of the object to
change (e.g. a hash table)
• No log(N) find (as with BSTs) – why not?
Other Priority Queue Operations
decreaseKey
• given a pointer to an object in the queue, reduce its priority value
increaseKey
• given a pointer to an object in the queue, increase its priority value
remove
• given a pointer to an object in the queue, remove it
buildHeap
• given a set of items, build a heap
Decrease key, Increase key, Remove key
void decreaseKey(MinHeap *heap, int posKey, int newVal){ void removeKey(MinHeap *heap, int posKey){
heap->arr[posKey]=newVal; decreaseKey(heap, posKey, Negative_Infinity);
heapifyUp(heap, posKey); extractMin(heap);
} }
18
BuildHeap (Floyd’s Method)
12 5 11 3 10 6 9 4 8 1 7 2
pretend it’s a heap and fix the heap-order property!
12
5 11
3 10 6 9
4 8 1 7 2
Build(this)Heap
12 12
5 11 5 11
3 10 2 9 3 1 2 9
4 8 1 7 6 4 8 10 7 6
12 12
5 2 1 2
3 1 6 9 3 5 6 9
4 8 10 7 11 4 8 10 7 11
Finish Build(ing)(this)Heap
3 2
4 5 6 9
12 8 10 7 11
Runtime?
Build Heap
void buildHeap(MinHeap *heap){
int i;
for (i=(heap->size/2); i>=1; i--){
heapifyDown(heap, i);
}
}
22
Complexity of Build Heap
• Note: size of a perfect binary tree doubles (+1)
with each additional layer
• At most n/4 percolate down 1 level
at most n/8 percolate down 2 levels
at most n/16 percolate down 3 levels…
log N
n n n n n log N i n
1 2 3 ... i i 1 i 2 n
4 8 16 i 1 2 2 i 1 2 2
O(n)