// 14:47 - 15:23 #include #include #define MAXSIZE 150 typedef struct node { char ch; int freq; struct node *l, *r; } node; typedef struct heap { int top; node **arr; } heap; node *newNode(char ch, int freq) { node *tr = malloc(sizeof(node)); tr->l = tr->r = NULL; tr->ch = ch; tr->freq = freq; return tr; } heap *newHeap() { heap *h = malloc(sizeof(heap)); h->top = 0; h->arr = malloc(sizeof(node *) * MAXSIZE); return h; } int parent(int i) { return (i - 1) / 2; } int left(int i) { return i * 2 + 1; } int right(int i) { return i * 2 + 2; } void swap(node **l, node **r) { node *tmp = *l; *l = *r; *r = tmp; } void heapify(heap *h, int i) { // from up to down int smallest = i; int l = left(i), r = right(i); if (l < h->top && h->arr[smallest]->freq > h->arr[l]->freq) { smallest = l; } if (r < h->top && h->arr[smallest]->freq > h->arr[r]->freq) { smallest = r; } if (smallest != i) { swap(&h->arr[smallest], &h->arr[i]); heapify(h, smallest); } } void insert(heap *h, node *tr) { int i = h->top++; h->arr[i] = tr; while (h->arr[i]->freq < h->arr[parent(i)]->freq) { swap(&h->arr[i], &h->arr[parent(i)]); i = parent(i); } } node *extractMin(heap *h) { node *res = h->arr[0]; h->arr[0] = h->arr[--h->top]; heapify(h, 0); return res; } node *makeHuffmanTree(heap *h) { node *l, *r; node *tmp; while (h->top > 1) { l = extractMin(h); r = extractMin(h); tmp = newNode('#', l->freq + r->freq); tmp->l = l; tmp->r = r; insert(h, tmp); } return extractMin(h); } void printCode(node *tr, char *buf) { int i = 0; while (buf[i] == '0' || buf[i] == '1') { node *cur = tr; while (cur->ch == '#') { if (buf[i] == '0') { cur = cur->l; } else { cur = cur->r; } i++; } printf("%c", cur->ch); } } int main(void) { heap *h = newHeap(); insert(h, newNode('a', 7)); insert(h, newNode('b', 19)); insert(h, newNode('c', 2)); insert(h, newNode('d', 6)); insert(h, newNode('e', 32)); insert(h, newNode('f', 3)); insert(h, newNode('g', 21)); insert(h, newNode('h', 10)); node *hTree = makeHuffmanTree(h); char buf[MAXSIZE]; fgets(buf, MAXSIZE, stdin); printCode(hTree, buf); return 0; }