#define MAX_WEIGHT 255 typedef struct { int weight; int traverseMark; int parent, lchild, rchild; }HTNode, *HuffmanTree; typedef char ** HuffmanCode; HuffmanTree HT = nil; HuffmanCode HC = nil; int *markSelect = nil; int min1 = 0; int min2 = 0; void HTselect(int length) { int min = MAX_WEIGHT; for (int i = 0; i < length; i++) { if ((HT[i].weight < min)&&(markSelect[i] == 0)) { min = HT[i].weight; min1 = i; } } markSelect[min1] = 1; min = MAX_WEIGHT; for (int i = 0; i < length; i++) { if ((HT[i].weight < min)&&(markSelect[i] == 0)) { min = HT[i].weight; min2 = i; } } markSelect[min2] = 1; return; } void HuffmanCoding(int *w, int n) { if (n <= 1) { return; } int m = 2*n - 1; HT = (HuffmanTree)malloc(m * sizeof(HTNode)); //used in HTSelect for marking the traversed node; markSelect = (int *)malloc(m * sizeof(int)); for (int q = 0; q < m; q++) { markSelect[q] = 0; } //init the node weight and status HuffmanTree p = HT; int i = 0; for (;i < n; ++i, ++p) { p->weight = w[i]; p->parent = MAX_WEIGHT; p->lchild = MAX_WEIGHT; p->rchild = MAX_WEIGHT; p->traverseMark = 0; } for (; i < m; ++i, ++p) { p->weight = 0; p->parent = MAX_WEIGHT; p->lchild = MAX_WEIGHT; p->rchild = MAX_WEIGHT; p->traverseMark = 0; } //constuct the Huffman tree //1...n is leaf nodes //n+1....m is not leaf nodes for (int j = n; j < m; j++) { HTselect(j); // HT[min1].parent = j; HT[min2].parent = j; HT[j].lchild = min1; HT[j].rchild = min2; HT[j].weight = HT[min1].weight + HT[min2].weight; } //print the Huffman tree p = HT; for (int j = 0; j < m; p++, j++) { NSLog(@"%d, %d, %d, %d", p->weight, p->parent, p->lchild, p->rchild); } } //get the Huffman code from the Huffman root to the leaf void HuffmanGetCode(int n) { int p = 2*n - 1 - 1; HC = (HuffmanCode)malloc(n * sizeof(char *)); char *cd = (char *)malloc(n * sizeof(char)); int cdlen = 0; while (p != MAX_WEIGHT) { if (HT[p].traverseMark == 0) { HT[p].traverseMark = 1; if (HT[p].lchild != MAX_WEIGHT) { p = HT[p].lchild; cd[cdlen++] = '0'; } else { HC[p] = (char *)malloc((cdlen + 1) *sizeof(char)); cd[cdlen] = '\0'; strcpy(HC[p], cd); } } else if (HT[p].traverseMark == 1) { HT[p].traverseMark = 2; if (HT[p].rchild != MAX_WEIGHT) { p = HT[p].rchild; cd[cdlen++] = '1'; } } else { cdlen--; HT[p].traverseMark = 0; p = HT[p].parent; } } for (int i = 0; i < n; i++) { printf("%s\n", HC[i]); } } //decode the information using the Huffman tree void HTDecode(int *code, int elementCount, int n) { int i = 0; int j = 0; int p = 2*elementCount - 1 - 1; int decode[MAX_WEIGHT]; while (i < n) { if (code[i] == 0) { if (HT[p].lchild != MAX_WEIGHT) { i++; p = HT[p].lchild; } else { decode[j++] = p; p = 2*elementCount - 1 - 1; } } else { if (HT[p].rchild != MAX_WEIGHT) { i++; p = HT[p].rchild; } else { decode[j++] = p; p = 2*elementCount - 1 - 1; } } } decode[j] = p; for(int i = 0; i <= j; i++) { printf("%d", decode[i]); } } -(void)main { int weight[5] = {4,5,8,9,12}; HuffmanCoding(weight, 5); HuffmanGetCode(5); int code[12] = {0,0,1,0,0,0,1,1,1,1,0,1}; HTDecode(code, 5, 12); }