Heaps and Priority Queues

COMP2521 20T2 ♢ Heaps & PQueues [0/17]
❖ Heaps

Heaps can be viewed as trees with top-to-bottom ordering

[Diagram:Pics/heap-bst.png]

COMP2521 20T2 ♢ Heaps & PQueues [1/17]
❖ ... Heaps


Heap characteristics ...

Since heaps are dense trees, depth = floor(log2N)+1

Insertion cost = O(logN),   Deletion cost = O(logN)

Heaps are typically used for implementing Priority Queues

COMP2521 20T2 ♢ Heaps & PQueues [2/17]
❖ ... Heaps

Heaps grow in regular (level-order) manner:

[Diagram:Pics/heap-growth.png]


Nodes are always added in sequence indicated by numbers

COMP2521 20T2 ♢ Heaps & PQueues [3/17]
❖ ... Heaps

Trace of growing heap ...

[Diagram:Pics/heap-grow.png]

COMP2521 20T2 ♢ Heaps & PQueues [4/17]
❖ ... 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:

[Diagram:Pics/heap-array.png]

COMP2521 20T2 ♢ Heaps & PQueues [5/17]
❖ ... 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=0,  nslots=ArraySize

One difference: we use indexes from 1..nitems

Note: unlike "normal" C arrays, nitems also gives index of last item

COMP2521 20T2 ♢ Heaps & PQueues [6/17]
❖ ... 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;
}

COMP2521 20T2 ♢ Heaps & PQueues [7/17]
❖ Insertion with Heaps

Insertion is a two-step process


[Diagram:Pics/heap-fixup.png]

COMP2521 20T2 ♢ Heaps & PQueues [8/17]
❖ ... 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);
}

COMP2521 20T2 ♢ Heaps & PQueues [9/17]
❖ ... 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;
}

COMP2521 20T2 ♢ Heaps & PQueues [10/17]
❖ ... Insertion with Heaps

Trace of fixUp after insertion ..

[Diagram:Pics/fixup-trace.png]

COMP2521 20T2 ♢ Heaps & PQueues [11/17]
❖ Deletion with Heaps

Deletion is a three-step process:

[Diagram:Pics/heap-fixdown.png]

COMP2521 20T2 ♢ Heaps & PQueues [12/17]
❖ ... 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;
}

COMP2521 20T2 ♢ Heaps & PQueues [13/17]
❖ ... 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;
   }
}

COMP2521 20T2 ♢ Heaps & PQueues [14/17]
❖ Cost Analysis


Recall:  tree is compact;  max path length = log2n

For insertion ...

For deletion ...
COMP2521 20T2 ♢ Heaps & PQueues [15/17]
❖ Priority Queues


Heap behaviour is exactly behaviour required for Priority Queue ...

So ...

typedef Heap PQueue;

void join(PQueue pq, Item it) { HeapInsert(pq,it); }

Item leave(PQueue pq) { return HeapDelete(pq); }

COMP2521 20T2 ♢ Heaps & PQueues [16/17]
❖ ... 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 usageO(N)*O(N)*O(N)O(N)O(N)*
joinO(N)O(1)O(N)O(1)O(logN)
leaveO(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

COMP2521 20T2 ♢ Heaps & PQueues [17/17]


Produced: 5 Jul 2020