建立哈夫曼树,求哈夫曼编码
2012-10-21 12:10
471 查看
/*建立哈夫曼树,就是每次从所有节点中选取两个权值最小且没有父亲的节点 *然后用这两个节点作为新节点的两个子树,新节点的权值等于两子树之和 *重复这个操作直到所有总节点数等于2*n-1 * */ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef struct node{ int weight; int parent,lchild,rchild; }HTNode,*HaffmanTree; typedef char **HaffmanCode; void select(HaffmanTree T, int n, int *s1, int *s2); //选取haffmanTree中权重最小的两个节点位置 void haffmanCoding(HaffmanTree *T, HaffmanCode *HC, int *w, int n); //建立haffmantree,求haffmancode void select(HaffmanTree T, int n, int *s1, int *s2){ int min=32767,nmin=32767; int vmin=0,vnmin=0; for(int i=0; i<n; i++){ if(T[i].parent!=0) continue; if(min>T[i].weight){ min = T[i].weight; vmin = i; }else if(nmin>T[i].weight){ nmin = T[i].weight; vnmin = i; } } *s1 = vmin,*s2 = vnmin; } void haffmanCoding(HaffmanTree *T, HaffmanCode *HC, int *w, int n){ //w存放n个字符的权值 if(n<=1) return; int i, s1, s2; int m = 2*n-1; *T = (HaffmanTree)malloc(sizeof(HTNode) * m); HaffmanTree p = *T; for(i=0; i<n; i++,p++,w++) *p = {*w,0,0,0}; //为前n个节点的weight赋值 for(;i<m;i++,p++) *p = {0,0,0,0}; //将n~2*n-1的节点初始化 for(i=n; i<m; i++){ select(*T,i,&s1,&s2); //悬着parent为0且weight最小的两个节点 (*T)[s1].parent = i; (*T)[s2].parent = i; (*T)[i].lchild = s1; (*T)[i].rchild = s2; (*T)[i].weight = (*T)[s1].weight+(*T)[s2].weight; } //从叶子到根逆向求haffmancode *HC = (HaffmanCode)malloc(sizeof(char *) * n); //非配n个字符编码的头指针向量 char *code = (char *)malloc(sizeof(char)*n); //非配临时存储编码的空间 code[n-1] = '\0'; int current,currentp; for(i=0; i<n; i++){ int start = n-1; for(current =i,currentp=(*T)[i].parent; currentp!=0; current=currentp,currentp=(*T)[currentp].parent){ if((*T)[currentp].lchild==current) code[--start] = '0'; else code[--start] = '1'; } (*HC)[i] = (char *)malloc(sizeof(char) * (n-start)); //为第i个字符编码分配空间 strcpy((*HC)[i], &code[start]); //将编码复制到HC } free(code); //释放工作空间 } int main(){ int w[5] = {4,6,8,1,3}; HaffmanTree HT; HaffmanCode HC; haffmanCoding(&HT, &HC, w, 5); for(int i=0; i<9; i++){ printf("%d\t",HT[i].weight); } printf("\n"); for(int i=0; i<5; i++) printf("%s\n",HC[i]); return 0; }
相关文章推荐
- 哈夫曼树的建立和哈夫曼编码
- 哈夫曼树的建立和哈夫曼编码的构造
- 哈夫曼树的建立以及哈夫曼编码
- 第十周项目实践 哈夫曼树的建立&&哈夫曼编码
- 哈夫曼树数据机构的建立及哈夫曼编码与解码的C++实现
- 二叉树的层次遍历、哈夫曼树及哈夫曼编码的建立
- 哈夫曼树的基本操作,(树的建立,带权路径长度,哈夫曼编码)
- 哈夫曼树与哈夫曼编码详解及C++模板实现
- ACM哈夫曼树建立、哈夫曼编码C++实现
- 哈夫曼树和哈夫曼编码
- 哈夫曼树的生成及哈夫曼编码
- 哈夫曼树以及哈夫曼编码的问题
- 哈夫曼树和哈夫曼编码
- 哈夫曼树的构建和求哈夫曼编码
- 哈夫曼树与哈夫曼编码、
- 哈夫曼树与哈夫曼编码
- 哈夫曼树和哈夫曼编码基本概念及构造(上篇)
- 哈夫曼树的构造与哈夫曼编码
- 哈夫曼树,哈夫曼编码