赫夫曼编译码器数课程设计Word文档下载推荐.docx
《赫夫曼编译码器数课程设计Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《赫夫曼编译码器数课程设计Word文档下载推荐.docx(27页珍藏版)》请在冰豆网上搜索。
如何采用有效的数据压缩技术引起了人们的极大重视。
从而产生了哈夫曼编码,它是一种应用广泛且非常有效的数据压缩技术,该技术一般可将数据压缩20%至90%,通常我们将压缩技术称为编码,解压缩过程称为解码。
树状结构简称为树,是一种以分支关系进行定义的层次结构,是十分重要的非线性数据结构,在计算机软件设计方面,有着广泛的应用。
1.1课程设计目的
本课程设计是为了让同学们了解数据结构的作用和意义。
数据结构是计算机科学与技术专业、计算机信息管理与应用专业和电子商务的专业的基础课,是十分重要的课程。
所有的计算机系统软件和应用软件都要用到各种类型的数据结构。
因此,想要更好地运用计算机来解决实际问题,仅掌握几种计算机程序设计语言是难以应付当前众多复杂的课题,想要有效地使用计算机,充分发挥它的性能,还必须学习和掌握好数据结构的有关知识,打好数据结构这门课的扎实基础,对于学习计算机专业的其他课程,如操作系统、软件工程、编译原理、人工智能等十分有益。
1.2课程设计背景
在这信息量发达的时代,随着社会的进步,信息不断地增多和更新,为了使信息更加快速、准确有的传递。
需要一个程序来完成。
1
1.3课程设计主要内容
本课程设计要求完成发送端对待传送数据的编码和接收端对传送来的数据的译码。
要实现五个功能:
接受原始数据、编码、译码、打印编码规则、将编码、译码存档。
通过系统的提示要建立哈夫曼树并对载入的原文件进行编码,并保存到txtfile.txt文件中,同时输出到屏幕。
最后将建立的赫夫曼树用某种树的储存方式储存后输出。
2
2方案设计
一套完整的编码译码系统应该具有以下功能:
(1)I:
初始化(initialization)。
从终端读入字符集大小n,以及n个字符和n个权值,建立赫夫曼树。
并将他存于文件hfmtree.txt中。
(2)E:
编码(encoding)。
利用已经建立好的赫夫曼树(如不在内存,则从文件hfmtree.txt中读入),对文件tobetree.txt中的正文进行编码。
然后将结果存入文件codefile.txt文件中。
(3)D:
译码(decoding)。
利用已经建立好的赫夫曼树将文件codefile.txt中的代码进行译码,将结果存入文件textfile.txt中。
(4)P:
印代码文件(print)。
将文件codefile.txt以紧凑格式显示在终端上。
每行50个代码。
同时将字符形式的编码文件写入到文件codeprin.txt中。
(5)T:
印赫夫曼树(treeprint)。
将已在内存中的赫夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的赫夫曼树写入文件treeprin.txt中。
3
3算法设计
3.1设计思想
赫夫曼树用邻接矩阵作为存储结构,借助静态链表来实现遍历。
3.2函数间的关系
函数间的关系如图3.1所示:
图3.1函数间的关系
3.3数据结构与算法设计
赫夫曼编\译码器的主要功能是先建立赫夫曼树,然后利用建好的赫夫曼树生成赫夫曼编码后进行译码。
在数据通信中,经常需要将传送的文字转换成由二进制字符0、1组成的二进制串,称之为编码。
构造一棵赫夫曼树,规定赫夫曼树中的左分之代表0,右分支代表1,则从根节点到每个叶子节点所经过的路径分支组成的0和1的序列便为该节点对应字符的编码,称之为赫夫曼编码。
最简单的二进制编码方式是等长编码。
若采用不等长编码,让出现频率高的字符具有较短的编码,让出现频率低的字符具有较长的编码,这样可能缩短传送电文的总长度。
赫夫曼树课用于构造使电文的编码总长最短的编码方案。
其主要流程图如图3.2所示:
4
图3.2赫夫曼树编\译码器流程图
5
4详细设计
赫夫曼树编、译码设计功能如下:
1.赫夫曼树抽象数据类型定义
ADTHuffmanCoding{
数据对象T:
具有相同特性的数据元素的集合
数据关系R:
满足最优二叉树的关系
基本操作P:
Init(&
t)
操作结果:
构造一个空赫夫曼树t。
encode()
利用赫夫曼树进行编码
Decode()
利用赫夫曼树进行译码
}
2.主函数
Voidmian()
{打印表头;
While(选择项不为q){
输入选择项;
Switch(选择项)
{Casei:
初始化;
break;
Casew:
输入要编码的字符;
break;
Casee:
编码字符;
Cased;
译码操作;
break;
Casep;
打印代码;
Caset;
打印赫夫曼树;
Default:
输入错误,重新选择;
3.求赫夫曼编码[5]
6
if(t[j].weight<
k&
&
t[j].parent==0)
k=t[j].weight,flag=j;
//flag为标志符,为不小于可能的值
t[flag].parent=1;
4.建赫夫曼树
HT[s1].parent=HT[s2].parent=i;
//将选好的两个结点设置成有同一个双亲结点
HT[i].lchild=s1;
//左孩子的权值
HT[i].rchild=s2;
//右孩子的权值
HT[i].weight=HT[s1].weight+HT[s2].weight;
//将两个权值相加作为新的权值
}
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
//为赫夫曼代码分配空间
5.将赫夫曼编码写入文件
用fputs(HC[i],htmTree);
fputs(r,htmTree);
fclose(htmTree)这些函数来实现编码写入文件;
6.完成译码功能并将译码写入文件
因为赫夫曼树建好后是左孩子结点旁标上0,右孩子结点上标上1
所以碰到1是用左孩子结点,2是用右孩子结点,可以用条件语句来实现。
if(i2=='
0'
)m=HT[m].lchild;
if(i2=='
1'
)m=HT[m].rchild;
fputs(outext,txtfile);
//将译码写入文件
7
5调试分析
1.本程序要执行首先要初始化一个赫夫曼树,按照用户设定的字符集大小,输入每个字符及其对应的出现概率即权值。
分别存放在w和z这两个变量中。
再利用这两个变量构造赫夫曼树。
2.执行输入字符命令时,程序将用户输入的字符存入文件tobetran.txt中。
以便执行下一步编码操作时自己从文件调用。
3.编码时,程序直接从tobetran.txt中读取字符,依次和字符数组变量z中元素项比较,找到之后,将编码表HC中对应编号的代码添加到分配的工作区间中,全部字符编码完成后将代码写入文件codefile.txt中。
4.译码时,程序从codefile中读取代码,按照代码从树根开始向叶子节点查找对应的字符,直到全部代码译码完成,再将译好的字符写入文件txtfile.txt中
5.打印编码操作,即从codefile.txt中读取代码,按要求输出到屏幕上。
8
6测试并列出测试结果
6.1测试方式
1.程序运行环境为DOS,执行文件为:
xzl的程序设计.exe
2.程序运行后,出现的界面如图6.1所示:
图6.1界面图
3.首先须进行初始化,按“i”执行,并输入节点数
9图6.2初始化
输入字符集数,对应的字符和权值,初始化赫夫曼树。
然后才能进行后续的操作。
4.选择“w”,输入要编码的字符。
5.选择“e”,对刚输入的字符进行编码。
6.选择“d”,对刚编码出的代码再译码回去。
7.选择“p”,打印编码出的代码。
8.选择“t”,代印赫夫曼树
9.选择“q”,退出程序。
6.2测试结果
1.初始化的内容如表6.1所示:
表6.1初始化的内容
“”
A
B
C
D
E
F
G
H
I
J
K
L
M
N
186
64
13
22
32
103
21
15
47
57
20
O
P
Q
R
S
T
U
V
W
X
Y
Z
63
48
80
23
18
16
2.初始化的结果如图6.3所示:
图6.3初始化的结果
3.将字符对应编码写入htmtree.txt,如图6.4所示:
10
图6.4将字符写入文件
4.字符对应的编码如图6.5所示:
图6.5字符对应的编码
5.输入要编码的字符如图6.6所示:
图6.6要编码的字符
11
6.编码:
图6.7编码操作
6.译码:
文件textfile.txt中内容:
THISPROGRAMISMYFAVORIT
其操作如图6.6所示:
图6.7译码操作
7打印编码:
图6.8打印编码操作
12
7.打印赫夫曼树如图6.8所示:
图6.9赫夫曼树
7总结
我通过将近一周的数据结构课程设计论文的学习,从中认识到怎样将知识迁移运用,深刻的知道了理论应用和实际相互间的密切联系,感受到了理论知识的重要,在今后的学习中一定会更加努力,认真,并且将理论与实践相结合。
在做这个课程设计论文的时候,我遇到过许多的问题,比如说,写程序以及调试程序时,有很多地方的错误都搞不懂,不过在老师的帮助下,我成功的调试出了程序,并运行出了结果,当时我感觉非常有成就感。
还有就是论文格式上,自己确实也有很多大一时学的东西都忘了,不过我通过问同学、老师以及网上XX,最终我还是把它搞懂了,总之,觉得这门课程我收获了很多课堂外不能学到的东西。
非常让我受益匪浅!
通过这门课程的学习,我确实体会到了自己的知识还有很多不足之处和个人能力的十分有限,只有通过同学、老师间的密切配合才能完成一项不错的工作。
不过从中我也体会到了在学习中也有无限的乐趣,可以将现实生活中某一问题用程序编写出来并将以调试,得出结果。
最后,在这里,我要十分感谢帮助过我的周老师和同学,是你们才让我顺利、成功的做出了这个课程设计!
!
14
致谢
在课程设计过程中遇到了很多问题,不过在周老师和和同学们的帮助下大部分都得以解决,首先要对他们表示感谢。
同时,我们也要感谢学校为我们提供了大量的图书以及设备,通过看书我们也学到了很多课堂上学不到的东西。
通过此次课程设计,我最大的收获是学会了自主学习,懂得了怎样运用c语言已经所学的数据结构知识相结合去实现不同问题的编程,也增进了与老师和同学们的交流、增进了相互之间的感情。
同时,对论文的格式要求有了更进一步的了解与掌握。
参考文献
[1]严蔚敏,吴伟民.数据结构:
C语言版.北京:
清华大学出版社,1997
[2]王昆仑,李红.数据结构与算法.北京:
中国铁道出版社
[3]周霭如,林伟健.C++程序设计基础.北京:
电子工业出版社,2005
[4]耿国华.数据结构.北京:
高等教育出版社,2005
[5]王卫东.数据结构辅导课.西安:
电子科技大学出版社,2001年
[6]赵文静.数据结构辅导.西安:
交通大学出版社,1999年
[7]刘大有等,《数据结构》(C语言版),高等教育出版社
[8]严蔚敏等,《数据结构》(C语言版),清华大学出版社
[9]WilliamFord,WilliamTopp,《DataStructurewithC++》清华大学出版社
[10]苏仕华等,数据结构课程设计,机械工业出版社
附录
程序清单如下:
#include<
iostream.h>
iomanip.h>
string.h>
malloc.h>
stdio.h>
//typedefintTElemType;
constintUINT_MAX=1000;
typedefstruct
{
intweight;
//权值
intparent,lchild,rchild;
//父节点,左孩子结点,右孩子结点
}HTNode,*HuffmanTree;
typedefchar**HuffmanCode;
//-----------全局变量-----------------------
HuffmanTreeHT;
//代表赫夫曼树
HuffmanCodeHC;
//代表赫夫曼编码
int*w,i,j,n;
char*z;
intflag=0;
intnumb=0;
//-----------------求赫夫曼编码-----------------------
voidline()
{cout<
<
"
\n--------------------------------------------------\n"
;
intmin(HuffmanTreet,inti)
{
intj,flag;
intk=UINT_MAX;
//取k为不小于可能的值
for(j=1;
j<
=i;
j++)
if(t[j].weight<
k=t[j].weight,flag=j;
t[flag].parent=1;
returnflag;
//返回标识符
//------------------------------------------
voidselect(HuffmanTreet,inti,int&
s1,int&
s2)
intj;
s1=min(t,i);
s2=min(t,i);
if(s1>
s2)//s1为最小的两个值中序号小的那个
{
j=s1;
s1=s2;
s2=j;
voidHuffmanCoding(HuffmanTree&
HT,HuffmanCode&
HC,int*w,intn)
intm,i,s1,s2,start;
intc,f;
HuffmanTreep;
char*cd;
if(n<
=1)
return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
//0号单元未用
for(p=HT+1,i=1;
i<
=n;
++i,++p,++w)
p->
weight=*w;
parent=0;
lchild=0;
rchild=0;
for(;
=m;
++i,++p)
for(i=n+1;
++i)//建赫夫曼树
{
select(HT,i-1,s1,s2);
cd=(char*)malloc(n*sizeof(char));
cd[n-1]='
\0'
for(i=1;
i++)
start=n-1;
for(c=i,f=HT[i].parent;
f!
=0;
c=f,f=HT[f].parent)
//从叶子到根逆向求编码
if(HT[f].lchild==c)
cd[--start]='
else
HC[i]=(char*)malloc((n-start)*sizeof(char));
strcpy(HC[i],&
cd[start]);
free(cd);
//--------------初始化赫夫曼链表---------------------------------
voidinit()
{//--------------------------------------------
flag=1;
intnum;
intnum2;
cout<
下面初始化赫夫曼链表"
endl<
请输入结点的个数n:
cin>
>
num;
n=num;
line();
w=(int*)malloc(n*sizeof(int));
//weight
z=(char*)malloc(n*sizeof(char));
//word
\n请依次输入"
n<
个字符(字符型)\n注意:
必须以回车结束:
endl;
chartemp[2];
line();
for(i=0;
n;
{
第"
i+1<
个字符:
gets(temp);
*(z+i)=*temp;
=n-1;
setw(6)<
*(z+i);
cout<
个权值(\n注意:
必须以回车结束):
个字符的权值:
num2;
*(w+i)=num2;
}
//输入部分结束------------------------------------------
HuffmanCoding(HT,HC,w,n);
//------------------------打印编码----------------------
字符对应的编码为:
//cout<
字符"
*(z+i-1)<
的编码"
puts(HC[i]);
//--------------------------将赫夫曼编码写入文件---------
下面将赫夫曼编码写入文件"
...................."
FILE*htmTree;
charr[]={'
'
'
};
if((htmTree=fopen("
htmTree.txt"
"
w"
))==NULL)
{
cout<
文件打开失败"
return;
}
fputs(z,htmTree);
for(i=0;
n+1;
fprintf(htmTree,"
%6d"
*(w+i));
fputs(HC[i],htmTree);
fclose(htmTree);
已