霍夫曼编码与译码
来源:互联网 发布:美国白银数据公布 编辑:程序博客网 时间:2024/05/16 23:41
树和二叉树的应用
一.实验题目:树和二叉树的应用
二.实验内容:哈夫曼编码设计
三.实验目的:掌握树和二叉树的概念及工作原理,运用其原理及概念完成上述实验题中的内容。
四、概要设计原理:
1.选择parent为-1且weight最小的两个结点。其序号分别为s1和s2
2.建立赫夫曼树叶
3.从叶子到根逆向求每个字符的赫夫曼编码
4.输出构造的树
5.输出得到的各权Huffman编码
#include<iostream>#include<iomanip>using namespace std;struct HaffNode{ int weight; int parent; int lchild; int rchild;};struct HaffCode{ int bit[10000]; //编码位 int start; //编码开始的位置 int weight; char c; //编码所对应的字符};/* 由于n个叶子结点,要合并n-1次。每次从 还无双亲(无双亲代表还未合并过) 的叶子结点中选择权值最小的两个叶子结点进行合并, 新结点下标为这两个叶子的双亲,新结点的权值为这两个叶子权值之和, 左孩子为最小结点下标,右孩子为次小结点下标,叶子值不需要,双亲为0。*/void CreateHaffman(int w[],int n,HaffNode ht[]){ //建立叶结点个数为n,权值为weight的哈夫曼树haffTree int i,j,m1,m2,x1,x2; //哈夫曼树haffTree初始化。n个叶结点的哈夫曼树共有2n-1个结点 for(i=0;i<2*n-1;i++) { if(i<n) ht[i].weight=w[i]; else ht[i].weight=0; ht[i].parent=0; ht[i].lchild=-1; ht[i].rchild=-1; } //构造哈夫曼树haffTree的n-1个非叶结点 for(i=0;i<n-1;i++) { m1=m2=1000; x1=x2=0; for(j=0;j<n+i;j++)//循环找出所有权重中,最小的二个值 { if(ht[j].weight<m1&&ht[j].parent==0) { m1=ht[j].weight; x1=j; } else if(ht[j].weight<m2&&ht[j].parent==0) { m2=ht[j].weight; x2=j; } } //将找出的两棵权值最小的子树合并为一棵子树 ht[x1].parent=n+i;//新结点下标为这两个叶子的双亲, ht[x2].parent=n+i; ht[n+i].weight=ht[x1].weight+ht[x2].weight;//新结点的权值为这两个叶子权值之和 ht[n+i].lchild=x1; ht[n+i].rchild=x2; }}void encoded(int n,char ch[],HaffNode ht[],HaffCode hc[]){ //由n个结点的哈夫曼树haffTree构造哈夫曼编码haffCode HaffCode cd; int child,parent,i,j; //求n个叶结点的哈夫曼编码 for(i=0;i<n;i++) { cd.start=n-1; cd.c=ch[i]; cd.weight=ht[i].weight;//取得编码对应权值的字符 child=i; parent=ht[child].parent;//由叶结点向上直到根结点 while(parent!=0) { if(ht[parent].lchild==child) cd.bit[cd.start]=0;//左孩子结点编码0 else cd.bit[cd.start]=1;//右孩子结点编码1 cd.start--; child=parent; parent=ht[child].parent; } //保存叶结点的编码和不等长编码的起始位 for(j=cd.start+1;j<n;j++)//重新修改编码,从根节点开始计数 hc[i].bit[j]=cd.bit[j]; hc[i].start=cd.start; hc[i].weight=cd.weight;//保存编码对应的权值 hc[i].c=cd.c; cout<<"字符"<<cd.c<<"的权值为:"<<hc[i].weight<<" code="; for(j=hc[i].start+1;j<n;j++) cout<<hc[i].bit[j]; cout<<endl; }}void transcode(int n,HaffNode ht[],HaffCode hc[]){ int a=2*n-2; char b; cout<<"请输入一串二进制编码(0,1以外的数结束)"<<endl; cin>>b; while((b=='0')||(b=='1')) { if(b=='0') a=ht[a].lchild; else a=ht[a].rchild; if(ht[a].lchild==-1) { cout<<hc[a].c; a=2*n-2; } cin>>b; }}int main(){ int w[1000];//权值数组 char ch[1000];//代码数组 int n,a; cout<<"共有叶子数:"<<endl; cin>>n; cout<<"依次输入每个叶子的权值:"<<endl; for(a=0;a<n;a++) cin>>w[a]; cout<<"依次输入每个叶子所代表代码:"<<endl; for(a=0;a<n;a++) cin>>ch[a]; HaffNode* ht=new HaffNode[2*n-1];//树结点数组 HaffCode* hc=new HaffCode[n];//编码数组 CreateHaffman(w,n,ht); encoded(n,ch,ht,hc); transcode(n,ht,hc); return 0;}
0 0
- 霍夫曼编码与译码
- 行程编码与译码
- 编码与译码-计算机网络
- 哈弗曼编码与译码
- 哈夫曼编码与译码
- 哈夫曼编码与译码
- Huffman编码与译码
- 汉明码编码与译码
- 哈夫曼树的编码与译码
- 哈弗曼编码与译码的问题
- 指令的编码与译码原理
- C语言实现哈夫曼编码与译码
- C语言:哈夫曼树的编码与译码
- 数据结构课程设计——编码与译码
- 南邮 OJ 1022 哈夫曼编码与译码
- 哈夫曼树的编码与译码(优化)
- 数据结构:哈夫曼树,哈夫曼编码与译码系统
- 哈夫曼树编码与译码解码运用
- java总结——内部类
- ubuntu12.04下安装mysql
- Java Serialization/序列化/反序列化
- java JSP javaBean
- Struts2数据传输的背后机制:ValueStack(值栈)
- 霍夫曼编码与译码
- 刨根问底:C++的移位操作
- [LeetCode1]3Sum
- 统计基础
- 1 网页中嵌入脚本代码的方法
- ffmpeg(12) ffmpeg中的各种数据结构
- Array和Dictionary作为常量时需要注意的地方
- 学会聪明的阅读
- SQLServer分页查询存储过程