HuffmanTree.h #ifndef HUFFMANTREE #define OK 1 #define ERROR 0 typedef void* ElemType; typedef char** HuffmanCode; typedef struct HTNode { ElemType weight; unsigned int parent, lchild, rchild; }*HuffmanTree; int init_HuffmanTree(HuffmanTree *); int Select(HuffmanTree, int, int *, int *); int create_HuffmanTree(HuffmanTree *, ElemType, int); int print_HuffmanTree(HuffmanTree, int); int HuffmanTree_Coding(HuffmanTree, HuffmanCode*, int); int print_HuffmanCodeTable(HuffmanTree, HuffmanCode, int); int HuffmanTree_DeCode(HuffmanTree, char *code[], int, int); #endif HuffmanTree.cpp #include<stdio.h> #include<stdlib.h> #include<string.h> #include"HuffmanTree.h" int init_HuffmanTree(HuffmanTree *HT) { *HT = NULL; return OK; } int Select(HuffmanTree HT, int pos, int *s1, int *s2) { //从下到上遍历,选择parent为0和weight最小的两个位置 int i; int min = pos; int min1 = pos; for(i = 1 ; i < pos ; i++) { if(HT[i].parent == 0 && *((int*)HT[i].weight) <= *((int*)HT[min].weight)) min = i; } for(i = 1 ; i < pos ; i++) { if(HT[i].parent == 0 && *((int*)HT[i].weight) <= *((int*)HT[min1].weight) && i != min) min1 = i; } if(min < min1) { *s1 = min; *s2 = min1; } else { *s1 = min1; *s2 = min; } return OK; } //建立赫夫曼树,w是权值,n是权值个数 int create_HuffmanTree(HuffmanTree *HT, ElemType w, int n) { if(n <= 1) return ERROR; int m = (n << 1) - 1; if(!((*HT) = (HTNode*)malloc((m + 1) * sizeof(HTNode)))) return ERROR; int *weight = (int*)w; HuffmanTree tmp = NULL; int i; //初始化,将权值保存到赫夫曼数组,然后进行建树 for(tmp = (*HT) + 1, i = 1 ; i <= n ; i++, tmp++, weight++) { if(!(tmp->weight = malloc(sizeof(int)))) return ERROR; *((int*)tmp->weight) = *weight; tmp->parent = 0; tmp->lchild = 0; tmp->rchild = 0; } for(; i <= m ; i++, tmp++) { if(!(tmp->weight = malloc(sizeof(int)))) return ERROR; *((int*)tmp->weight) = 0; tmp->parent = 0; tmp->lchild = 0; tmp->rchild = 0; } //建立赫夫曼树 int s1, s2; for(i = n + 1 ; i <= m ; i++) { Select(*HT, i - 1, &s1, &s2); (*HT)[i].lchild = s1; (*HT)[i].rchild = s2; (*HT)[s1].parent = i; (*HT)[s2].parent = i; *((int*)(*HT)[i].weight) = *((int*)(*HT)[s1].weight) + *((int*)(*HT)[s2].weight); } return OK; } int print_HuffmanTree(HuffmanTree HT, int n) { if(HT == NULL) return ERROR; int m = (n << 1) - 1; int i = 1; printf("id/tweight/tparent/tlchild/trchild/n"); while(i <= m) { printf("%2d/t%d/t%d/t%d/t%d/n", i, *((int*)HT[i].weight), HT[i].parent , HT[i].lchild, HT[i].rchild); i++; } return OK; } //求赫夫曼编码 int HuffmanTree_Coding(HuffmanTree HT, HuffmanCode *HC, int n) { if(n <= 1 || HT == NULL) return ERROR; //为赫夫曼编码表分配空间 if(!((*HC) = (HuffmanCode)malloc((n + 1) * sizeof(char*)))) return ERROR; char *cd; int i; int p; //为编码的字符串分配空间 if(!(cd = (char*)malloc(n * sizeof(char)))) return ERROR; cd[n - 1] = '/0'; for(i = 1 ; i <= n ; i++) { int start = n - 1; int w; //从叶子到根逆向求编码 for(w = i, p = HT[i].parent ; p != 0 ; w = p, p = HT[p].parent) { if(HT[p].lchild == w) cd[--start] = '0'; else cd[--start] = '1'; } if(!((*HC)[i] = (char*)malloc((n - start) * sizeof(char)))) return ERROR; strcpy((*HC)[i], &cd[start]); } free(cd); return OK; } int print_HuffmanCodeTable(HuffmanTree HT, HuffmanCode HC, int n) { if(n <= 1) return ERROR; int i; for(i = 1 ; i <= n ; i++) { printf("%3d: ", *((int*)HT[i].weight)); printf("%s/n", HC[i]); } return OK; } //通过翻译code的字符串编码,求得指定的权值,n为权值个数,n1为编码个数 int HuffmanTree_DeCode(HuffmanTree HT, char *code[], int n, int n1) { if(HT == NULL) return ERROR; int i = 0; int j = 0; int p; int m = (n << 1) - 1; while(n1 > 0) { j = 0; int tmp = m; while(*(code[i] + j) != '/0') { if(*(code[i] + j) == '0') p = HT[tmp].lchild; else p = HT[tmp].rchild; if(HT[p].lchild == 0 && HT[p].rchild == 0) { printf("%d ", *((int*)HT[p].weight)); break; } tmp = p; j++; } i++; n1--; } return OK; }