Problem 6.2
Analysis of d-ary heaps
A d-ary heap is like a binary heap, but (with one possible exception) non-leaf nodes have $d$ children instead of 2 children.
- How would you represent a $d$-ary heap in an array?
- What is the height of a $d$-ary heap of $n$ elements in terms of $n$ and $d$?
- Give an efficient implementation of
EXTRACT-MAX
in a $d$-ary max-heap. Analyze its running time in terms of $d$ and $n$.- Give an efficient implementation of
INSERT
in $d$-ary max-heap. Analyze its running time in terms of $d$ and $n$.- Give an efficient implementation of
INCREASE-KEY(A, i, k)
, which flags an error if $k < A[i]$, but otherwise sets $A[i] = k$ and then updates the $d$-ary max-heap structure appropriately. Analyze its running time in terms of $d$ and $n$.
Representation
We just modify LEFT
, RIGHT
and PARENT
. We can get the $k$-th child of the
$i$th node with $d i + k - 1$ and the parent with $\lfloor i/d \rfloor$ (when
indexing is 1-based).
Height
Of course it's $\log_dn$.
Implementation
The implementation is below. The complexity of EXTRACT-MAX
is
$\O(d\log_dn)$, while the other two are $\O(\log_dn)$.
C code
#include <stdio.h> #include <stdlib.h> #include <limits.h> #define PARENT(i,d) ((i - 1) / d) #define CHILD(i,c,d) (3 * i + c + 1) typedef struct { int *elements; int d; int heap_size; int length; } heap_t; void max_heapify(heap_t *heap, int i) { int largest = i; for (int k = 0; k < heap->d; k++) { int child = CHILD(i, k, heap->d); if (child < heap->heap_size && heap->elements[child] > heap->elements[largest]) largest = child; } if (largest != i) { int tmp = heap->elements[i]; heap->elements[i] = heap->elements[largest]; heap->elements[largest] = tmp; max_heapify(heap, largest); } } int extract_max(heap_t *heap) { int max = heap->elements[0]; heap->elements[0] = heap->elements[heap->heap_size - 1]; heap->heap_size--; max_heapify(heap, 0); return max; }; void increase_key(heap_t *heap, int i, int key) { if (key < heap->elements[i]) { exit(0); fprintf(stderr, "new key is smaller than current key\n"); } while (i > 0 && heap->elements[PARENT(i,heap->d)] < key) { heap->elements[i] = heap->elements[PARENT(i,heap->d)]; i = PARENT(i,heap->d); } heap->elements[i] = key; } void insert(heap_t *heap, int key) { heap->heap_size++; heap->elements[heap->heap_size - 1] = INT_MIN; increase_key(heap, heap->heap_size - 1, key); }