哈夫曼树——C++实现
2015-10-12 20:46
411 查看
#include <iostream> using namespace std; #define MAXBIT 10 #define MAXVALUE 10000 #define MAXLEAF 100 #define MAXNODE MAXLEAF*2-1 //定义哈夫曼树编码类型 typedef struct{ char bit[MAXBIT]; //存放叶子结点字符编码过后的二进制编码 int start; //存放叶子结点二进制编码在code[]数组里的起始数组位置 int length; //存放二进制编码的位数 }CodeType; //定义哈夫曼树结点类型 typedef struct { char ch; //字符 int weight; //哈夫曼树结点的权值 int lchild,rchild,parent; //哈夫曼树结点的左孩子,右孩子,父节点 }Htnode; void createHFMTree(Htnode h[MAXNODE],int n); //构造哈夫曼树 void showCode(CodeType code[MAXNODE],Htnode h[MAXNODE],int n); //显示叶子的字符和其对应的二进制编码 void compileCode(char str[],int n,CodeType code[MAXLEAF],Htnode h[MAXNODE]);//输入字符串,得到二进制编码 void decompileCode(char num[],int n,CodeType code[MAXLEAF],Htnode h[MAXNODE]);//输入二进制编码得到字符串 void main(){ Htnode h[MAXNODE]; CodeType code[MAXLEAF]; char str[100]; //存放输入的需要编译的的字符串 char num[100]; //存放输入的需要编译的二进制字符串 int n; //输入的叶子结点数 //哈夫曼编码器 cout<<"-----------------哈夫曼编码器------------------\n"; cout<<"请输入叶子结点数:"; cin>>n; createHFMTree(h,n); showCode(code,h,n); //哈夫曼译码器 cout<<"-----------------哈夫曼译码器------------------\n"; cout<<"请输入字符:\n"; cin>>str; compileCode(str,n,code,h); cout<<"请输入需要译码的编码:\n"; cin>>num; decompileCode(num,n,code,h); } //构造哈夫曼树 void createHFMTree(Htnode h[MAXNODE],int n){ int i,j,m1,m2,s1,s2; for(i=0;i<2*n-1;i++){ //所有节点初始化 h[i].weight=0; h[i].parent=-1; h[i].lchild=-1; h[i].rchild=-1; } cout<<"请输入叶子节点的字符:"; for(i=0;i<n;i++){ getchar(); cin>>h[i].ch; } cout<<"请输入叶子节点的权重:"; for(i=0;i<n;i++){ getchar(); cin>>h[i].weight; } for(i=0;i<n-1;i++){ m1=m2=MAXVALUE; //m1和m2存储叶子结点权值的最小值和次小值 s1=s2=0; //s1和s2存储m1和m2的位置 for(j=0;j<n+i;j++){ if(h[j].weight<m1&&h[j].parent==-1){ m2=m1; s2=s1; m1=h[j].weight; s1=j; } else if(h[j].weight<m2&&h[j].parent==-1){ m2=h[j].weight; s2=j; } } h[n+i].weight=h[s1].weight+h[s2].weight;//父结点的权重是左孩子和右孩子的权重之和 h[s1].parent=h[s2].parent=n+i; h[n+i].lchild=s1;h[n+i].rchild=s2; } } //显示叶子的字符和其对应的二进制编码 void showCode(CodeType code[MAXNODE],Htnode h[MAXNODE],int n){ int i,j,k,c,p; CodeType cd; for(i=0;i<n;i++){ code[i].length=0; code[i].start=0; k=code[i].start; cd.start=n-1; c=i; p=h[c].parent; while(p!=-1){ //有父节点 if(h[p].lchild==c) //孩子是父节点的左孩子 cd.bit[cd.start]='0'; else cd.bit[cd.start]='1'; cd.start--; c=p; p=h[c].parent; } for(j=cd.start+1;j<n;j++,k++){ code[i].bit[k]=cd.bit[j]; code[i].length++; //length计算存放的二进制编码的位数 } } for(i=0;i<n;i++){ //输出每个叶子节点的哈夫曼编码 cout<<h[i].ch<<"的编码是:"; for(j=code[i].start;j<code[i].length;j++) cout<<code[i].bit[j]; cout<<endl; } } //输入字符串,得到二进制编码 void compileCode(char str[],int n,CodeType code[MAXLEAF],Htnode h[MAXNODE]){ for(int i=0;str[i]!='\0';i++){ for(int j=0;j<n;j++){ if(str[i]==h[j].ch){ for(int k=code[j].start;k<code[j].length;k++) cout<<code[j].bit[k]; } } cout<<" "; } cout<<endl<<endl; } //输入二进制编码得到字符串 void decompileCode(char num[],int n,CodeType code[MAXLEAF],Htnode h[MAXNODE]){ int j=2*n-2; //哈夫曼树根结点的位置 for(int i=0;num[i]!='\0';i++){ if(num[i]=='0'){ j=h[j].lchild; } else if(num[i]=='1'){ j=h[j].rchild; } if(j<n){ //j大于等于n表示的都是除叶子结点以外的哈夫曼树结点 cout<<h[j].ch<<" "; j=2*n-2; } } cout<<endl; }
相关文章推荐
- android 代码实现控件之间的间距
- [Android]在代码里运行另一个程序的方法
- AVL树-自平衡二叉查找树(Java实现)
- 肯特·贝克:改变人生的代码整理魔法
- 网页恶意代码的预防
- 动易2006序列号破解算法公布
- 文件遍历排序函数
- 高手写的Tracer-Flash代码调试类代码下载
- CSS代码缩写技巧
- 非主流Q-zOne代码代码搜集第1/2页
- Ruby实现的矩阵连乘算法
- CreateWeb.vbs 代码
- C#插入法排序算法实例分析
- Lua 学习笔记之C API 遍历 Table实现代码
- Lua中编译执行代码相关的函数详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析