Huffman编码的设计与应用实验.docx
《Huffman编码的设计与应用实验.docx》由会员分享,可在线阅读,更多相关《Huffman编码的设计与应用实验.docx(10页珍藏版)》请在冰豆网上搜索。
Huffman编码的设计与应用实验
深圳大学实验报告
课程名称:
数据结构实验与课程设计
实验项目名称:
Huffman编码的设计与应用实验
学院:
计算机与软件学院
专业:
软件工程
指导教师:
杨芳
报告人:
赖跃辉学号:
2013150367班级:
8
实验时间:
2013-10-23
实验报告提交时间:
10-23
教务处制
一、实验目的
1、理解树、二叉树的链式存储结构(三叉链表)
2、掌握Huffman树的生成算法
3、掌握运用Huffman树,生成对应字符的Huffman编码算法
4、掌握运用字符的Huffman编码,将一个字符串编码成一串Huffman编码序列方法
5、掌握利用Huffman树(编码),对一串Huffman编码序列进行解码的方法
二、实验要求
熟悉C++语言编程
熟练使用C++语言,实现Huffman编码和解(译)码算法
三、实验内容
本次实验有两项内容:
(一)Huffman编码的设计与应用
1、问题描述
给定n个字符及其对应的权值,构造Huffman树,并进行huffman编码和译(解)码。
构造Huffman树时,要求左子树根的权值小于右子树根的权值。
进行Huffman编码时,假定Huffman树的左分支上编码为‘0’,右分支上编码为‘1’。
2、算法
构造Huffman树算法:
⑴、根据给定的n个权值(w1,w2,…,wn)构成n棵二叉树的集合F={T1,T2,…,Tn},其中每棵二叉树Ti中只有一个权值为wi的根结点
⑵、在F中选取两棵根结点的权值最小的树,作为左、右子树构造一棵新的二叉树,且置其根结点的权值为其左、右子树权值之和
⑶、在F中删除这两棵树,同时将新得到的二叉树加入F中
⑷、重复⑵,⑶,直到F只含一棵树为止
Huffman编码算法:
⑴、从Huffman树的每一个叶子结点开始
⑵、依次沿结点到根的路径,判断该结点是父亲结点的左孩子还是右孩子,如果是左孩子则得到编码‘0’,否则得到编码‘1’,先得到的编码放在后面
⑶、直到到达根结点,编码序列即为该叶子结点对应的Huffman编码
Huffman译(解)码算法:
⑴、指针指向Huffman树的根结点,取第一个Huffman码
⑵、如果Huffman码为‘0’,将指针指向当前结点的左子树的根结点;如果Huffman码为‘1’,将指针指向当前结点的右子树的根结点
⑶、如果指针指向的当前结点为叶子结点,则输出叶子结点对应的字符;否则,取下一个Huffman码,并返回⑵
⑷、如果Huffman码序列未结束,则返回⑴继续译码
3、输入
第一行:
样本字符个数,假设为n。
第二行,n个字符(用空格隔开)
第三行,n个字符对应的权值(用空格隔开)
第四行,待编码的字符串
第五行,待译码的Huffman码序列
4、输入样本
4
abcd
9326
abcd
111001010
5、输出
第一行,每个字符对应的Huffman编码(用空格隔开)
第二行,字符串对应的Huffman编码序列
第三行,Huffman码序列对应的字符串
6、输出样本
010110011
010110011
Dcba
四、程序清单
#include
#include
usingnamespacestd;
constintN=100;
structhuffmantree{
charc;
unsignedintweight;
unsignedintlson,rson,parent;
charcode[10];
};huffmantreeHT[N];
voidSelect(intn,int*s1,int*s2)
{
unsignedinti,s;
s=0;
for(i=1;i<=n;i++)//从第1位开始,
if(HT[i].parent==0)
{
if(s==0)s=i;
if(HT[s].weight>HT[i].weight)s=i;//如果比HT[s].weights换值
}
*s1=s;
s=0;
for(i=1;i<=n;i++)
if(HT[i].parent==0&&i!
=*s1)//从第1位开始,
{
if(s==0)s=i;
if(HT[s].weight>HT[i].weight)s=i;//如果比HT[s].weights换值
}
*s2=s;
}//选择n之前最少的的两个没有操作过的数字
voidcreatetree(int*w,char*c,intn)
{
if(n<=1)return;
intm=2*n-1,i;//构建2*n-1个数
for(i=1;i<=n;i++)
{
HT[i].c=c[i-1];
HT[i].weight=w[i-1];
HT[i].lson=0;
HT[i].rson=0;
HT[i].parent=0;
}//初始化HT[i],先弄好前n位
while(i<=m)
{
HT[i].weight=0;
HT[i].lson=0;
HT[i].rson=0;
HT[i].parent=0;
i++;
}//初始化HT[i],弄n往后到m的数所有的都为0
for(i=n+1;i<=m;i++)
{
ints1,s2;
Select(i-1,&s1,&s2);//选择从第1到i-1位最小的两位数
HT[s1].parent=i;
HT[s2].parent=i;//构建第s1和s2位的父母
HT[i].lson=s1;
HT[i].rson=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;//构建第i位的孩子和权值
}
}
voidhuffmancoding(intn)
{
inti,j,k,f,c,start;
intm=10;
charcd[10];
cd[9]='\0';
for(i=1;i<=n;i++)//从第一位开始到第n位
{
start=m-1;
for(c=i,f=HT[i].parent;f!
=0;c=f,f=HT[f].parent)//从第节点i,沿着父母找到根
{
if(HT[f].lson==c){cd[--start]='0';}
else{cd[--start]='1';}//逆着赋值
}
for(j=0;jHT[i].code[j]='\0';
}
}
intshowcode(intn,char*str)
{
inti,c,root;
root=2*n-1;
c=root;
for(i=0;i{
if(HT[c].lson==0&&HT[c].rson==0)//如果节点没有孩子,这肯定是有效的字符
{
cout<c=root;//输出,又从头开始比较
}
if(str[i]=='0'){if(HT[c].lson==0)return0;c=HT[c].lson;}
else{if(HT[c].rson==0)return0;c=HT[c].rson;}//c沿着孩子的路走下去
}
cout<return1;
}
intmain()
{
intn,w[N],i;
charc[N],str1[N],str2[N];
//freopen("cin.txt","r",stdin);
cin>>n;
for(i=0;icin>>c[i];
for(i=0;icin>>w[i];//对应输入字母和权值
createtree(w,c,n);
huffmancoding(n);//调用函数
for(i=1;icout<cout<cin>>str1;
for(intj=0;j{
for(i=1;i<=n;i++)
if(HT[i].c==str1[j])
{
cout<break;
}
}//匹配每个字母,输出其对应的编码
cout<cin>>str2;
showcode(n,str2);//调用函数
return0;
}
五、程序运行时截图
六、实验心得与体会(实验中遇到的问题及解决方案,或写点感想)
这次的作业,稍微比上几次都要难,程序里面细节真的很重要,并且现在的这个程序,一定要分块来写才比较好写,如果没有很好的分块,程序实现起来很难操作。
分好后,就要对每个块要认真考虑其中的细节,还有稍微错一个块,解决它还是比较轻松的,但是还是应该要多点写这个算法,把里面容易出错的地方一次一次发现。
指导教师批阅意见:
成绩评定:
指导教师签字:
年月日
备注:
注:
1、报告内的项目或内容设置,可根据实际情况加以调整和补充。
2、教师批改学生实验报告时间应在学生提交实验报告时间后10日内。