终于把Huffman算法实现了
#include <stdio.h> #include <malloc.h> #include <string.h> typedef struct huffman{ int weight; int parent,lchild,rchild; }HTNode,*HuffmanTree; int n; char buf[MAX_LEN]; void HuffmanCoding(HuffmanTree &HT,int w[],int len_w); void writeHC(HuffmanTree &HT,HTNode &leaf,int i,char buf[],int &cur); int min(HuffmanTree &T,int &len_w); int main(){ HuffmanTree HT; while(scanf("%d",&n) != EOF){ int *pw = (int *)malloc( (n + 1) * sizeof(int)); if(!pw){ printf("Memory Error!,Please Try Again."); continue; } for(int i = 1; i <= n; i++){//输入n个字符对应的权值(分别映射为从a -- z) scanf("%d",pw + i); } HuffmanCoding(HT,pw,n);//进行huffman编码,结果存在HC中 free(pw); } return 0; } void HuffmanCoding(HuffmanTree &HT,int w[],int len_w){ int m = 2 * len_w - 1; HT = (HuffmanTree)malloc(sizeof(HTNode) * (m + 1)); if(!HT){ printf("Something Error in Build HuffmanTree!"); exit(-1); } /* 注意给叶子结点赋值和初始化后,各结点依然是离散状态*/ for(int i = 1 ; i <= len_w; i++){//给叶子结点赋值 HT[i].weight = w[i];//1 -- len_w号为叶子 HT[i].parent = 0; HT[i].lchild = HT[i].rchild = 0; } for(int i = len_w + 1; i <= m; i++){//剩下的非叶子结点,都是度为2的结点,分别初始化 HT[i].weight = 0; HT[i].parent = 0; HT[i].lchild = HT[i].rchild = 0; } /*贪心算法,构建huffman树*/ int search_area = len_w;//搜索最小值范围 int start = len_w + 1;//其它非叶子结点指针 for(;;){ int min1 = min(HT,search_area); int min2 = min(HT,search_area); if(min1 == min2){//当只有棵树时,huffman树建立完毕 HT[min1].parent = 0;//根节点parent域指向空2 break; } HT[start].weight = HT[min1].weight + HT[min2].weight; HT[start].lchild = min2; HT[start].rchild = min1; HT[min1].parent = HT[min2].parent = start; search_area++; start++; len_w--; } int cur = 0; for(int i = 1; i <= n;i++){ writeHC(HT,HT[i],i,buf,cur); cur = 0; } free(HT); } int min(HuffmanTree &T,int &len_w){//len_w为叶子结点的个数 int m; for(int i = 1; i <= len_w; i++){ if(T[i].parent == 0){ m = i; break; } } for(int i = 1; i <= len_w;i++){ if(T[m].weight > T[i].weight && T[i].parent == 0){ m = i; } } T[m].parent = -1; return m; } void writeHC(HuffmanTree &HT,HTNode &leaf,int i,char buf[],int &cur){ if(leaf.parent == 0){ buf[cur] = '\0'; for(int i = cur - 1; i >=0 ; i--) printf("%c",buf[i]); printf("\n"); return; }else{ if(HT[leaf.parent].lchild == i){ buf[cur++] = '1'; writeHC(HT,HT[leaf.parent],leaf.parent,buf,cur); } if(HT[leaf.parent].rchild == i){ buf[cur++] = '0'; writeHC(HT,HT[leaf.parent],leaf.parent,buf,cur); } } }