#include #include #include #include // from Van Wyk, chapter 10, page 233++ typedef struct heapslot heapslot; struct heapslot { int key; int value; } ; #define MAXHEAP 4 heapslot * heap; int heapnum; int maxheap; bool empty(){ return heapnum == 0; } void demand(int cond, char * msg) { if (! cond) { fprintf(stderr, msg); exit(1); } return; } void printHeap(){ printf("HEAP: "); for(int i = 1; i <= heapnum; i++){ printf("[%d: %d/%d] ", i, heap[i].key, heap[i].value); } printf("\n"); } int findmin(){ demand( !empty(), "findmin not allowed on empty heap\n"); return heap[1].value; } void initheap(){ heapnum = 0; maxheap = MAXHEAP; heap = malloc(maxheap * sizeof(heap)); heap[0].key = INT_MIN; } void swap(heapslot *s1, heapslot *s2){ heapslot temp; printf("SWAP: %d <=> %d\n", s1->key, s2->key); temp = *s1; *s1 = *s2; *s2 = temp; } void insert(int key, int value){ int cur, parent; printf("INSERT: %d, %d ", key, value); //demand(heapnum < maxheap, "heap overflow\n"); while(heapnum >= maxheap) { maxheap *= 2; printf("\nExpanding heap size to %d\n", maxheap); heap = realloc(heap, sizeof(*heap) * maxheap); demand(heap != 0, "malloc fail in insert\n"); } cur = ++heapnum; heap[cur].key = key; heap[cur].value = value; parent = cur/2; while (heap[parent].key > heap[cur].key) { printf("\n--"); printHeap(); demand(parent > 0, "inserted item rising past root\n"); swap(&heap[parent], &heap[cur]); cur = parent; parent = cur/2; } printHeap(); } void deletemin(){ int cur, child; printf("DELETEMIN: "); demand(! empty(), "deletemin not allowed on empty heap\n"); heap[1] = heap[heapnum--]; cur = 1; child = 2; while (child <= heapnum) { printf("\n--"); printHeap(); if (child < heapnum && heap[child+1].key < heap[child].key) child++; if (heap[cur].key > heap[child].key) { demand(child <= heapnum, "falling past leaves\n"); swap(&heap[cur], &heap[child]); cur = child; child = 2*cur; } else break; } printHeap(); } int main(int argc, char ** argv){ initheap(); //printHeap(); if (argc > 1) { for (int i=1; i < argc; i++) { int val = atoi(argv[i]); if (val > 0) { insert(val, val*val); } else { deletemin(); } } exit(1); } else { fprintf(stderr, "Usage: heap [numbers]+\n"); exit(1); } }