/* Huffman decoding. * In order to get huffman codes of elements with different weights, we * build a huffman tree, which is also called strict binary tree ,and then * we trace from leafs to the root. The left child makes code 0 and the right * child makes code 1. When we arrive at the root, the codes stream with * opposite sequence is what we want. Of course, there is no need to do the * "reversing" work if we build the codes stream form finish to start. * * * The decoding progress is just opposite to encoding. We go from root to * leafs according to the codes stream. Code 0 make us go left and code 1 * makes us go right. The property of huffman tree(also called strict binary * tree) makes all combinations of 0 and 1 go to the right direction. We should * only worry about the non-0 and non-1 codes; But, it`s possible that * the codes stream is not complete. However, I do not consider this case as * an error. Because, in case of this situation, it must be the last character. * * by:double; version:0.1; date:2009-08-01. */ #include "/usr/c/head.h" #define INT_MAX ((int)(~0U >> 1)) #define MAX 100 typedef struct huffman_tree_node { unsigned int weight; unsigned int parent, lchild, rchild; }huffman_tree_node, *huffman_tree; typedef char ** huffman_code; status get_child(huffman_tree p, int n, int *c1, int *c2) { int i, temp, m, min; m = 0; min = INT_MAX; for (i = 1; i < n; ++i) if (p[i].parent == 0 && min > p[i].weight) { m = i; min = p[i].weight; } *c1 = m; m = 0; min = INT_MAX; for (i = 1; i < n; ++i) if (p[i].parent == 0 && min > p[i].weight && i != *c1) { m = i; min = p[i].weight; } *c2 = m; if (*c1 > *c2) { temp = *c1; *c1 = *c2; *c2 = temp; } return OK; } status huffman_coding(huffman_tree *HT, huffman_code *HC, int *w, int n) { int i, m, c1, c2, start, c, f; huffman_tree p; char * cd; m = 2 * n - 1; *HT = (huffman_tree)malloc(sizeof(huffman_tree_node) * (m + 1)); if (!(*HT)) exit(OVERFLOW); for (i = 1, p = *HT + 1; i <= n; ++i, ++p, ++w) { p->weight = *w; p->parent = p->lchild = p->rchild = 0; } for (; i <= m; ++i, ++p) p->weight = p->parent = p->lchild = p->rchild = 0; for (i = n + 1; i <= m; ++i) { get_child(*HT, i, &c1, &c2); (*HT)[i].lchild = c1; (*HT)[i].rchild = c2; (*HT)[i].weight = (*HT)[c1].weight + (*HT)[c2].weight; (*HT)[c1].parent = (*HT)[c2].parent = i; } *HC = (huffman_code)malloc(sizeof(char *) * (n + 1)); if (!(*HC)) exit(OVERFLOW); cd = (char *)malloc(sizeof(char) * n); if (!cd) exit(OVERFLOW); cd[n - 1] = '/0'; for (i = 1; i <= n; ++i) { start = n - 1 ; for (c = i, f = (*HT)[i].parent; f != 0; c = f, f = (*HT)[f].parent) { if ((*HT)[f].lchild == c) cd[--start] = '0'; else cd[--start] = '1'; } (*HC)[i] = (char *)malloc(sizeof(char) * (n - start)); if (!(*HC)[i]) exit(OVERFLOW); strcpy((*HC)[i], cd + start); } free(cd); return OK; } status print_code(huffman_code HC, int n) { int i; for (i = 1; i <= n; ++i) printf("%s/n", HC[i]); return OK; } status decode(huffman_tree HT, int n, char * p) { int i; int flag; i = 2 * n - 1; while (*p) { /* *p is the necessary and sufficient condition*/ if (*p == '0') i = HT[i].lchild; else if (*p == '1') i = HT[i].rchild; else { printf("Only 0 or 1 is permited!/n"); exit(ERROR); } flag = 0; if (HT[i].lchild == 0) { printf("%d/t", HT[i].weight); i = 2 * n - 1; flag = 1; } ++p; } printf("/n"); if (!flag) printf("The code is not complete!/n"); /* The possibility of incomplete codes stream.*/ return OK; } int main(void) { huffman_tree HT; huffman_code HC; int temp, n, weight[MAX], i; char code[1000]; printf("How many:"); SCAN_INT(n, temp); if (n <= 1 || n > MAX - 1) { printf("No need or input error!/n"); exit(ERROR); } for (i = 1; i <= n; ++i) { printf("No.%d:", i); SCAN_INT(weight[i], temp); } huffman_coding(&HT, &HC, weight + 1, n); printf("The huffman codes are:/n"); print_code(HC, n); printf("Input the codes:"); scanf("%s", code); decode(HT, n, code); return 0; }