课程设计报告哈夫曼编码.docx
《课程设计报告哈夫曼编码.docx》由会员分享,可在线阅读,更多相关《课程设计报告哈夫曼编码.docx(19页珍藏版)》请在冰豆网上搜索。
课程设计报告哈夫曼编码
学号:
课程设计
题目哈夫曼编码
学院计算机科学与技术
专
计算机科学与技术
业
班
级
姓
名
指导
教师
2000
10年7月2日
课程设计任务书
学生姓名:
拉巴珠久
专业班级:
计算机0806
指导教师:
姚寒冰
工作单位:
计算机科学系
题目:
哈夫曼编码
初始条件:
输入一段英文字符,试为该文中的每个字符编制相应的哈夫曼码。
(1)1:
初始化(Initialization)。
对输入的一段央文中的每个字符统计其权值,建立哈夫曼树;
(2)E:
编码(Encoding)。
利用已建好的哈夫曼树,对每个字符进行编码。
(3)D:
译码(Decoding)。
利用已建好的每个编码,对输入的一个由0、1组成的序列进行译码;
(4)P:
印代码文件(Print)。
将每个字符编的哈夫曼码和译码结果显示在终端上。
测试用例见题集p149。
要求完成的主要任务:
(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)
课程设计报告按学校规定格式用A4纸打印(书写),并应包含如下内容:
1、问题描述
简述题目要解决的问题是什么。
2、设计
存储结构设计、主要算法设计(用类C语言或用框图描述)、测试用例设计;
3、调试报告
调试过程中遇到的问题是如何解决的;对设计和编码的讨论和分析。
4、经验和体会(包括对算法改进的设想)
5、附源程序清单和运行结果。
源程序要加注释。
如果题目规定了测试数据,则运行结果要包含这些测试数据和运行输出,
6、设计报告、程序不得相互抄袭和拷贝;若有雷同,则所有雷同者成绩均为0分。
时间安排:
1、第18周(6月28日至7月2日)完成。
2、7月2日08:
30到计算中心检查程序、交课程设计报告、源程序(CD盘)。
指导教师签名:
年月日
系主任(或责任教师)签名:
年月日
1设计题目1
2问题描述1
3.1数据结构设计1
3.2主要算法设计3
3.3测试用例设计6
4调试报告7
5结束语7
六、课程设计参考资料8
附录9
F1源代码9
F2运行结果16
哈夫曼编码
1设计题目
哈夫曼编码
2问题描述
输入一段英文字符,试为该文中的每个字符编制相应的哈夫曼码。
(1)I:
初始化(Initialization)。
对输入的一段英文中的每个字符统计其权值,建立哈夫曼树;
(2)E:
编码(Encoding)。
利用已建好的哈夫曼树,对每个字符进行编码。
(3)D:
译码(Decoding)。
利用已建好的每个编码,对输入的一个由0、1组成的序列进行译码;
(4)P:
印代码文件(Print)。
将每个字符编的哈夫曼码和译码结果显示在终端上。
3•设计
3.1数据结构设计
抽象数据类型二叉树的定义如下:
ADTBinaryTree{
数据对象D:
D是具有相同特性的数据元素的集合。
数据关系R:
基本操作P:
InitBiTree(&T);
操作结果:
构造空二叉树To
DestroyBiTree(&T);
初始条件:
二叉树T存在。
操作结果:
销毁二叉树To
CreateBiTree(&T,definition);
初始条件:
definition给出二叉树T的定义。
操作结果:
按definition构造二叉树T。
ClearBiTree(&T);
初始条件:
二叉树T存在。
操作结果:
将二叉树T清为空树。
BiTreeEmpty(T);
初始条件:
二叉树T存在。
操作结果:
若T为空二叉树。
则返回TRUE,否贝UFALSE
BiTreeDepth(T);
初始条件:
二叉树T存在。
操作结果:
返回T的深度。
Root(T);
初始条件:
二叉树T存在。
操作结果:
返回T的根。
Value(T,e);
初始条件:
二叉树T的存在,e是T中某个结点。
操作结果:
返回e的值。
Assign(T,&e,value);
初始条件:
二叉树T存在,e是T中某个结点。
操作结果:
结点e赋值为value。
Parent(T,e);
初始条件:
二叉树T存在,e是T中某个结点。
操作结果:
若e是T的非根结点,贝U返回它的双亲,否则返回“空”。
DeleteChild(T,p,LR);
初始条件:
二叉树T存在,p指向T中某个结点,LR为0或1。
操作结果:
根据LR为0或1,删除T中p所指结点的左或右子树。
InsertChild(T,p,LR,c);
初始条件:
二叉树的T存在,p指向T中某个结点,LR为0或1,非空二叉树c与T不相交且右子树为空。
P所指结点
操作结果:
根据LR为0或1插入c为T中p所指结点的左或右子树的原有左或右子树则成为c的右子树。
}
3.2主要算法设计
程序中一共定义了一个结构体和三个函数如下:
structHuffman〃定义指向结点的结构体
{
intweight;//权值
intparent,lchild,rchild;〃父亲结点和左右结点的位置
};
voidselect(Huffman*ht,inti,int&s1,int&s2)
{//选择权值较小的两个作为新的叶子结点,用于huffman的构造
intj,k;
k=s1;
for(j=0;j
if(s1!
=j&&j!
=s2&&ht[j].parent==0)
{
s1=j;break;
}
for(j=0;j
if(s2!
=j&&s1!
=j&&j!
=k&&ht[j].parent==0)
{
s2=j;break;
}
for(j=1;j<=i;j++)
if(ht[j].weightvht[s1].weight&&ht[j].parent==0)s1=j;
if(s1==s2)
{
for(j=0;j
if(s2!
=j&&s1!
=j&&j!
=k&&ht[j].parent==0)
{
s2=j;break;
}
}
for(j=0;j<=i;j++)
if(ht[j].weightvht[s2].weight&&ht[j].parent==0&&j!
=s1)s2=j;
voidHuffmancoding(Huffman*ht,char**&hc,intk){//对haffman进行编码
intm,s1=0,s2=0,start,c,i,f,j;
char*cd;
m=2*k-1;
for(i=k;i{
select(ht,i-1,s1,s2);/调用select函数
ht[s1].parent=i;
ht[s2].parent=i;
ht[i].lchild=s1;
ht[i].rchild=s2;
ht[i].weight=ht[s1].weight+ht[s2].weight;
}
for(i=0;i<=k-1;i++)/对每个叶子结点进行编码
{
cd=newchar[k];
hc[i]="";
for(j=0;jcd沪';
start=k-1;
for(c=i,f=ht[i].parent;f!
=0;c=f,f=ht[f].parent)if(ht[f].lchild==c){cd[start--]='0';}elsecd[start--]='1';
hc[i]=&cd[start+1];
}
voidfrequency(int*&w,charstr[100],int*&c,intn,int&k)
{//涵数用于统计输入的字符的权w(出现的次数)。
inti,j,m;
for(i=0;i{
if(i==0){c[0]=0;continue;}
for(j=0;j
if(str[j]==str[i]){c[i]=c[j];break;}
if(j==i){c[i]=++k;}
}
for(j=0;j<=k;j++)
{
for(m=0;mif(c[m]==j)w[j]++;
}
3.3测试用例设计
已知某系统在通信联络中只可能出现八种字符,其概率分别为0.05;0.29;0.07;0.08;
0.14;0.23;0.03;0.11试设计哈夫曼编码。
设权w=(5,29;7;8;14;23;3;1)n=8,则m=15,构造哈夫曼树。
如下图:
哈夫曼编码:
1
1
■0110
2
►
10
3
x
•1110
4
1
”1111
5
1
.110
6
1
•00
7
1
>0111
8
1
>010
4调试报告
程序调试:
(1.)当01序列解码成字符串时,要注意是否与已得出的字符串的编码匹配,如果不匹配,就把它后面的01序列截掉,不进行解码。
(2.)&表示函数的参数是按地址传递的,当函数有多个返回值而无法用return实现时,通常使用这种。
比如:
voidfrequency(int*&w,charstr[1OO],int*&c,intn,int&k)
5结束语
经验和体会:
通过一个星期的努力,总算把课程设计给完成了,这是一个坚苦而又漫长的过程。
是啊,读了那么多年的书,课程设计可是第一次。
看着劳动成果,很欣慰!
通过这次课程设计之后我觉得自己对书上知识的掌握有很大的欠缺,看了题目都不知道怎么下手,一点头
绪都没有,之后自己认真看了一遍书上的知识,查阅了一些网上资料,我能熟练掌握了二叉树,然后在此基础上掌握理解haffman树和编码,熟知了二叉树的性质。
可是这点小进展远远不够,这只是一个小小的开始,只能程序的大概轮廓可以写出来了。
但是有很多的细节和特殊情况没法写上去,例如:
用于huffman的构造;用于对haffman进行编码;用于统计输入的字符的权w(出现的次数);实现这些的程序不知道该怎么写。
后来经过同学的帮助和指导慢慢地程序里用到的函数通过哪些语句来实现它,那些关键的函数怎样
把它们有机结合起来等等,总之,在同学的多次指导下一个完整的程序写出来了,我也努
力地去读懂它,发现自己隐约读懂了它!
真正的收获更多是思想上的,让我认识程序的复杂,自己的微不足道,学无止境”
头一次认识的这么深刻,察觉自己的不足。
在这次编程中,同学帮了我很多,我一个人是不能完成的。
查书,查资料,请教同学的过程就是我提高的过程,总之,通过这次的课程设计,我发现程序设计最重要的就是上机实践,以前只是看书,觉得看懂了,但是真正到机子上写程序时感觉无从下手,没有什么头绪,可能就是因为实际上机操作的太少了,以后需要在这方面好好地加强了。
以后的学习生活真的要踏踏实实,自己的计算机生涯必定是坎坷的,信心受挫了。
六、课程设计参考资料
[1]《数据结构(STL框架)》王晓东编著,清华大学出版社,出版或修订时间:
2009年9月
[2]《数据结构(C语言版)》,严蔚敏,吴伟民编著,出版社:
清华大学出版社,出版或修订时间:
1997年4月
[3]《数据结构习题集(C语言版)》严蔚敏,吴伟民,米宁编著,清华大学出版社,出版或修订时间:
1999年2月
起草人:
杨克俭
2010-6-22
附录
F1源代码
#include
usingnamespacestd;
structHuffman〃定义指向结点的结构体
{
intweight;〃权值
intparent,lchild,rchild;〃父亲结点和左右结点的位置
};
voidselect(Huffman*ht,inti,int&s1,int&s2)
{〃选择权值较小的两个作为新的叶子结点,用于huffman的构造。
intj,k;
k=s1;
for(j=0;j
if(s1!
=j&&j!
=s2&&ht[j].parent==0)
{
s1=j;break;
}
for(j=0;j
if(s2!
=j&&s1!
=j&&j!
=k&&ht[j].parent==0)
{
s2=j;break;
}
for(j=1;j<=i;j++)
if(ht[j].weightvht[s1].weight&&ht[j].parent==0)s1=j;
if(s1==s2)
{
for(j=0;j
if(s2!
=j&&s1!
=j&&j!
=k&&ht[j].parent==0)
{
s2=j;break;
}
}
for(j=0;j<=i;j++)
if(ht[j].weightvht[s2].weight&&ht[j].parent==0&&j!
=s1)s2=j;
}
voidHuffmancoding(Huffman*ht,char**&hc,intk){//对haffman进行编码
intm,s1=0,s2=0,start,c,i,f,j;
char*cd;
m=2*k-1;
for(i=k;i{
select(ht,i-1,s1,s2);/调用select函数
ht[s1].parent=i;
ht[s2].parent=i;
ht[i].lchild=s1;
ht[i].rchild=s2;
ht[i].weight=ht[s1].weight+ht[s2].weight;
}
for(i=0;i<=k-1;i++)/对每个叶子结点进行编码
{
cd=newchar[k];hc[i]="";
for(j=0;jcd[j]='';
start=k-1;
for(c=i,f=ht[i].parent;f!
=0;c=f,f=ht[f].parent)if(ht[f].lchild==c){cd[start--]='0';}elsecd[start--]='1';
hc[i]=&cd[start+1];
}
voidfrequency(int*&w,charstr[100],int*&c,intn,int&k){//涵数用于统计输入的字符的权w(出现的次数)。
inti,j,m;
for(i=0;i{
if(i==0){c[0]=0;continue;}
for(j=0;j
if(str[j]==str[i]){c[i]=c[j];break;}
if(j==i){c[i]=++k;}
}
for(j=0;j<=k;j++)
{
for(m=0;mif(c[m]==j)w[j]++;
}
intmain()
{
inti=O,m,j,n=O,k=O,l,r=O,t;
int*w,*c;
char**hc;
charstr[100],str1[100];
Huffman*ht;//定义需要使用的变量
for(i=0;i<100;i++){str[i]='';str1[i]='';}
coutvv"请输入需要编码的字符串:
"<cin>>str;
i=0;
while(str[i]!
=''){n++;i++;}
n--"/while循环统计输入的字符串中的字符数
c=newint[n];
for(i=0;iw=newint[n];
for(i=0;ifrequency(w,str,c,n,k);
m=2*n-1;〃计算总的结点数
ht=newHuffman[m];
hc=newchar*[n*sizeof(char*)];
for(i=0;i<=k;i++)//代表叶子结点数
{
ht[i].weight=w[i];
ht[i].parent=ht[i].lchild=ht[i].rchild=0;
}
for(;i{
ht[i].weight=ht[i].parent=ht[i].lchild=ht[i].rchild=0;
}
k++;
Huffmancoding(ht,hc,k);
coutvv"各字符及其相应的编码为:
"<for(i=0;i{
for(l=0;l
{
if(c[i]==c[l])break;
}
if(l==i)
{
cout<for(j=0;j{
if(hc[c[i]][j]!
='0'&&hc[c[i]][j]!
='1')break;
elsecout«''<}
cout«endl;
}
}
coutvv"您输入的字符串的编码为:
"<for(i=0;i{
for(j=0;j{
if(hc[c[i]][j]!
='0'&&hc[c[i]][j]!
='1')break;elsecout<}
}cout<i=0;
cout<<"请输入需要译码的字符串:
"<cin>>str1;
m=0;
while(str1[i]!
=''){m++;i++;}
m--;
j=0;
cout<<"译码后为:
"<while(j{
for(l=0,i=r;l{
if(hc[j][l]!
='0'&&hc[j][l]!
='1')
{
r=i;
for(t=0;tif(c[t]==j){cout<j=0;
break;
}
if(str1[i]!
=hc[j][l]){j++;break;}
}
译码。
if((i==m)&&(hc[j][l]=='0'||hc[j][l]=='1'))cout"<if(i==m)break;
}
cout<return0;
F2运行结果
tCB'kDnr11mhAn■angnhS9gees
各玮及其相应的錮码为*
»1e61n001
"1
g1113
i1080
ti1«1D
Bill
k1011
h0«6
悠输入的字符串的编码为土
漕输入禰熹解码的字符串丄
貝码后九
HinAgnn
帽需?
.需要镐国歯宇诗串:
P^essA"*ke^tocontinue-
uilhheJteuuj^l^ui
卷字衙及其相应的顒码为,
40
1
d1
0
1
0
Jci
&
1
1
hH
d
1
B1
a
s
j1
1
0
0
y1
t
H
1
11
1
1
e
a1
1
1
1
i闻
&
0
悠输入的字符串的駕芮为:
H1LH10101leBUSeSBll0001011109110111101111B1BS0
金输人需要解码的字符串:
HQ001B丄1HW11BB10111111L11111111
辭码后为:
i1ikhckn^jiiiii但最后&<2个年符无注瞬码6
IPresskeytocontinue
本科生课程设计成绩评定表
班级:
计算机0806姓名:
拉巴珠久学号:
0120710340401
序
号
评分项目
满
分
实
得分
1
学习态度认真、遵守纪律
20
2
设计结果
40
3
设计报告规范(包括设计图、设计代码)
40
总得分/等级
评语:
注:
优(90—100分)、良(80—89分)、中(70-79分)、及格(60—69分)、
60分以下为不及格
指导教师签名: