❖ Heaps |
Heaps can be viewed as trees with top-to-bottom ordering
❖ ... Heaps |
Heap characteristics ...
Insertion cost = O(logN), Deletion cost = O(logN)
Heaps are typically used for implementing Priority Queues
❖ ... Heaps |
Heaps grow in regular (level-order) manner:
Nodes are always added in sequence indicated by numbers
❖ ... Heaps |
BSTs are typically implemented as linked data structures.
Heaps are often implemented via arrays (assumes we know max size)
Simple index calculations allow navigation through the tree:
ItemItemItem
❖ ... Heaps |
Heap data structure:
typedef struct HeapRep {
Item *items; // array of Items
int nitems; // #items in array
int nslots; // #elements in array
} HeapRep;
typedef HeapRep *Heap;
Initialisation: nitems=0nslots=
One difference: we use indexes from 1..nitems
Note: unlike "normal" C arrays, nitems
❖ ... Heaps |
Creating new heap:
Heap newHeap(int N)
{
Heap new = malloc(sizeof(HeapRep));
Item *a = malloc((N+1)*sizeof(Item));
assert(new != NULL && a != NULL);
new->items = a; // no initialisation needed
new->nitems = 0; // counter and index
new->nslots = N; // index range 1..N
return new;
}
❖ Insertion with Heaps |
Insertion is a two-step process
❖ ... Insertion with Heaps |
Insertion into heap:
void HeapInsert(Heap h, Item it)
{
// is there space in the array?
assert(h->nitems < h->nslots);
h->nitems++;
// add new item at end of array
h->items[h->nitems] = it;
// move new item to its correct place
fixUp(h->items, h->nitems);
}
❖ ... Insertion with Heaps |
Bottom-up heapify:
// force value at a[i] into correct position void fixUp(Item a[], int i) { while (i > 1 && less(a[i/2],a[i])) { swap(a, i, i/2); i = i/2; // integer division } } void swap(Item a[], int i, int j) { Item tmp = a[i]; a[i] = a[j]; a[j] = tmp; }
❖ Deletion with Heaps |
Deletion is a three-step process:
❖ ... Deletion with Heaps |
Deletion from heap (always remove root):
Item HeapDelete(Heap h)
{
Item top = h->items[1];
// overwrite first by last
h->items[1] = h->items[h->nitems];
h->nitems--;
// move new root to correct position
fixDown(h->items, 1, h->nitems);
return top;
}
❖ ... Deletion with Heaps |
Top-down heapify:
// force value at a[i] into correct position // note that N gives max index *and* # items void fixDown(Item a[], int i, int N) { while (2*i <= N) { // compute address of left child int j = 2*i; // choose larger of two children if (j < N && less(a[j], a[j+1])) j++; if (!less(a[i], a[j])) break; swap(a, i, j); // move one level down the heap i = j; } }
❖ Cost Analysis |
Recall: tree is compact; max path length = log2n
For insertion ...
❖ Priority Queues |
Heap behaviour is exactly behaviour required for Priority Queue ...
join(PQ,it)it = leave(PQ)
typedef Heap PQueue;
void join(PQueue pq, Item it) { HeapInsert(pq,it); }
Item leave(PQueue pq) { return HeapDelete(pq); }
❖ ... Priority Queues |
Heaps are not the only way to implement priority queues ...
Comparison of different Priority Queue representations:
| Array (sorted) |
Array (unsorted) |
List (sorted) |
List (unsorted) |
Heap | |
| space usage | O(N)* | O(N)* | O(N) | O(N) | O(N)* |
| join | O(N) | O(1) | O(N) | O(1) | O(logN) |
| leave | O(N) | O(N) | O(1) | O(N) | O(logN) |
| is empty? | O(1) | O(1) | O(1) | O(1) | O(1) |
for a Priority Queue containing N items
* If fixed-size array (no realloc), choose max N that might ever be needed
Produced: 5 Jul 2020