数据结构课程设计实验报告哈夫曼树的应用Word文件下载.docx
- 文档编号:20077931
- 上传时间:2023-01-16
- 格式:DOCX
- 页数:19
- 大小:91.91KB
数据结构课程设计实验报告哈夫曼树的应用Word文件下载.docx
《数据结构课程设计实验报告哈夫曼树的应用Word文件下载.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计实验报告哈夫曼树的应用Word文件下载.docx(19页珍藏版)》请在冰豆网上搜索。
分步实施:
1)初步完成总体设计,搭好框架,确定人机对话的界面,确定函数个数;
2)完成最低要求:
完成功能1;
3)进一步要求:
完成功能2和3。
有兴趣的同学可以自己扩充系统功能。
要求:
1)界面友好,函数功能要划分好
2)总体设计应画一流程图
3)程序要加必要的注释
4)要提供程序测试方案
5)程序一定要经得起测试,宁可功能少一些,也要能运行起来,不能运行的程序是没有价值的。
二、概要设计
(一)设计思想
哈夫曼树用邻接矩阵作为存储结构,借助静态链表来实现遍历。
(二)函数间的关系如图所示:
(三)数据结构与算法设计
哈夫曼编\译码器的主要功能是先建立哈夫曼树,然后利用建好的哈夫曼树生成哈夫曼编码后进行译码。
在数据通信中,经常需要将传送的文字转换成由二进制字符0、1组成的二进制串,称之为编码。
构造一棵哈夫曼树,规定哈夫曼树中的左分之代表0,右分支代表1,则从根节点到每个叶子节点所经过的路径分支组成的0和1的序列便为该节点对应字符的编码,称之为哈夫曼编码。
最简单的二进制编码方式是等长编码。
若采用不等长编码,让出现频率高的字符具有较短的编码,让出现频率低的字符具有较长的编码,这样可能缩短传送电文的总长度。
哈夫曼树课用于构造使电文的编码总长最短的编码方案。
其主要流程图如下图所示。
哈夫曼树编\译码器流程图
三、详细设计
功能函数模块划分
voidmain()
voidprinthead()
voidprintree(HuffmanTreeHT,intw)//打印赫夫曼树
voidcoprint(HuffmanTreestart,HuffmanTreeHT)//打印代码文件
voidprintcode()//打印代码
voiddecode()//完成译码功能
voidencode()//完成编码功能
voidinputcode()
voidinit()
voidHuffmanCoding(HuffmanTree&
HT,HuffmanCode&
HC,int*w,intn)
voidselect(HuffmanTreet,inti,int&
s1,int&
s2)
intmin(HuffmanTreet,inti)//找两个最小的权值
(1)哈夫曼编码:
首先定义函数,找出全部权值中最小的两个,然后定义一个变量,使他始终成为最小的那个。
再将两个函数最为叶子结点,并得到一个父亲节点,此父亲节点的权值为其叶子节点的权值之和。
并将此父亲节点的权值与其余权值进行比较,重新选出两个最小的权值,再进行上述步骤,直到所有权值形成了一颗二叉树,而此二叉树就是我们所说的最优二叉树,即哈夫曼树。
以上为哈夫曼树的建立过程,下面为哈夫曼编码的过程,从叶子节点出发,若此叶子节点为其父亲节点的左孩子,则将其编码为0,若为右孩子,则将其编码为1,然后为其父亲节点编码,若为祖先的左孩子,则变为0,为右孩子则为1,依次向上一层进行遍历,直到遍历到根节点,停止编码。
(2)译码:
对于已经建好的哈夫曼树,要对其进行译码,首先从根出发如果编码为0,则往左孩子遍历,如果编码为1,则往右孩子遍历,直到遍历到叶子节点,便求得该子串相应的字符。
(3)初始化哈夫曼链表:
首先输入结点个数,再将字符及权值输入,调用编码函数,得到每个字符编码并将其输出。
最后将哈夫曼编码写入文件。
(4)完成编码功能:
打开目录下文件tobetran.txt,读取里面的字符,对其进行编码后,将编码写入目录下的codefile.txt中。
(5)完成译码功能:
打开根目录下codefile.txt文件,读取里面的编码,对其中的编码进行译码,并将得到的内容写入根目录下的文件txtfile.txt中。
(6)打印编码
(7)打印哈夫曼树
四、调试分析和测试结果
(一)初始化哈夫曼链表
(二)编码字符
(三)编码
(四)译码
(五)打印编码
(六)打印哈夫曼函数
五、心得体会与总结
对于本次课程设计,主要是需要掌握哈夫曼树建立、哈夫曼编码以及哈夫曼译码的算法。
并能将其熟练应用于编译码器的完成。
经过这次的课程设计,使我们更加了解了数据结构,也更深入地了解了哈夫曼编码与译码算法,课程设计的题目比我们平常的实验内容要难,完成它不仅需要有厚实的语言基础,而且还要熟练掌握哈夫曼编码与译码的算法,另外对于文件的基本操作也需要熟悉。
通过数据结构课程设计,我的C++语言水平有了比较大的提高其中。
C++语言关于类的操作理解的比以前深刻不少。
另外是数据结构方面的提高对哈夫曼树的构造及哈夫曼码方面也有不少的提高。
在项目中也出现了很多的问题,最大的问题就是对程序设计框架结构的不了解,在实现代码与功能的连接时经常会出现各种不同的错误,在实现一些功能时系统常常会报错。
许多错误不知从哪修改以致拖了整个设计的后腿。
课程设计中,既回顾了很多以前的东西,也发现了很多的问题以前都没遇见过的,收获很大。
通过本次数据结构的课程设计,我学习了很多在上课没懂的知识,并对求哈夫曼树及哈夫曼编码/译码的算法有了更加深刻的了解,更巩固了课堂中学习有关于哈夫曼编码的知识。
此次哈夫曼树的应用系统的设计让自己对数据结构的了解更深入。
六、参考文献
《C++面向对象程序设计教程》(第三版)陈维兴林小茶编着清华大学出版社
《数据结构》(C语言版)严蔚民吴伟民编着清华大学出版社
六、附录
源程序:
#include<
iostream.h>
iomanip.h>
string.h>
malloc.h>
stdio.h>
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"
;
}
{
intj,flag;
intk=UINT_MAX;
//取k为不小于可能的值
for(j=1;
j<
=i;
j++)
if(t[j].weight<
k&
&
t[j].parent==0)
k=t[j].weight,flag=j;
t[flag].parent=1;
returnflag;
//返回标识符
//--------------------使s1成为最小权值----------------------
intj;
s1=min(t,i);
s2=min(t,i);
if(s1>
s2)//s1为最小的两个值中序号较小的那个
{
j=s1;
s1=s2;
s2=j;
}
intm,i,s1,s2,start;
intc,f;
HuffmanTreep;
char*cd;
if(n<
=1)
return;
m=2*n-1;
//申请2n-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)//初始化
p->
for(i=n+1;
++i)//建哈夫曼树
{
select(HT,i-1,s1,s2);
//调用建子树的函数
HT[s1].parent=HT[s2].parent=i;
//i是s1和s2的父节点
HT[i].lchild=s1;
HT[i].rchild=s2;
//s1和s2是i的儿子节点
HT[i].weight=HT[s1].weight+HT[s2].weight;
//i的权值为s1和s2的和
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
//分配n个字符编码的头指针向量
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]='
0'
else
1'
HC[i]=(char*)malloc((n-start)*sizeof(char));
//为第i个字符编码分配空间
strcpy(HC[i],&
cd[start]);
//从cd复制编码(串)到HC
free(cd);
//释放工作空间
//--------------初始化哈夫曼链表---------------------------------
flag=1;
intnum;
intnum2;
下面初始化哈夫曼链表"
endl<
请输入结点的个数n:
cin>
>
num;
//输入结点个数
n=num;
w=(int*)malloc(n*sizeof(int));
//权值
z=(char*)malloc(n*sizeof(char));
//字符
\n请依次输入"
n<
个字符(字符型)\n注意:
必须以回车结束:
endl;
chartemp[2];
for(i=0;
n;
i++)//输入字符
第"
i+1<
个字符:
gets(temp);
*(z+i)=*temp;
line();
=n-1;
i++)//输出字符
cout<
setw(6)<
*(z+i);
个权值(\n注意:
必须以回车结束):
i++)//输入权值
个字符的权值:
cin>
num2;
*(w+i)=num2;
HuffmanCoding(HT,HC,w,n);
//调用哈夫曼编码
//------------------------打印编码----------------------
字符对应的编码为:
i++)//输出所有编码
puts(HC[i]);
//--------------------------将哈夫曼编码写入文件---------
下面将赫夫曼编码写入文件"
FILE*htmTree;
charr[]={'
'
'
};
if((htmTree=fopen("
htmTree.txt"
"
w"
))==NULL)
文件打开失败"
fputs(z,htmTree);
n+1;
i++)
fprintf(htmTree,"
%6d"
*(w+i));
fputs(r,htmTree);
fputs(HC[i],htmTree);
fclose(htmTree);
已将字符与对应编码写入根目录下文件htmTree.txt中"
}//init
//---------------------获取字符并写入文件---------------------------------
FILE*virttran,*tobetran;
charstr[100];
if((tobetran=fopen("
tobetran.txt"
不能打开文件"
请输入你想要编码的字符"
gets(str);
fputs(str,tobetran);
获取字符成功"
fclose(tobetran);
//------------------------------------------------------
下面对目录下文件tobetran.txt中的字符进行编码"
FILE*tobetran,*codefile;
rb"
if((codefile=fopen("
codefile.txt"
wb"
char*tran;
i=99;
tran=(char*)malloc(100*sizeof(char));
//为tran分配100个字节
while(i==99)
if(fgets(tran,100,tobetran)==NULL)
{
cout<
break;
}
for(i=0;
*(tran+i)!
='
for(j=0;
{
if(*(z+j-1)==*(tran+i))
{
fputs(HC[j],codefile);
puts(HC[j]);
if(j>
n)
{
cout<
字符错误,无法编码!
break;
}
}
}
编码工作完成"
编码写入目录下的codefile.txt中"
fclose(codefile);
free(tran);
//--------------------------------------------------
下面对根目录下文件codefile.txt中的字符进行译码"
FILE*codef,*txtfile;
if((txtfile=fopen("
Textfile.txt"
if((codef=fopen("
r"
char*tbdc,*outext,i2;
intio=0,i,m;
unsignedlonglength=10000;
tbdc=(char*)malloc(length*sizeof(char));
//分配空间
fgets(tbdc,length,codef);
outext=(char*)malloc(length*sizeof(char));
*(tbdc+i)!
i++)//进入循环
i2=*(tbdc+i);
if(HT[m].lchild==0)
*(outext+io)=*(z+m-1);
io++;
m=2*n-1;
i--;
elseif(i2=='
)m=HT[m].lchild;
)m=HT[m].rchild;
*(outext+io)='
fputs(outext,txtfile);
译码完成"
内容写入根目录下的文件txtfile.txt中"
free(tbdc);
free(outext);
fclose(txtfile);
fclose(codef);
//---------------------------------------------
下面打印根目录下文件CodePrin.txt中编码字符"
-----------------------------------------------------------------\n"
FILE*CodePrin,*codefile;
if((CodePrin=fopen("
CodePrin.txt"
char*work3;
work3=(char*)malloc(51*sizeof(char));
do
if(fgets(work3,51,codefile)==NULL)
不能读取文件"
fputs(work3,CodePrin);
puts(work3);
}while(strlen(work3)==50);
free(work3);
打印工作结束"
fclose(CodePrin);
{chart='
if(start!
=HT)
FILE*TreePrint;
if((TreePrint=fopen("
TreePrint.txt"
a"
创建文件失败"
}
numb++;
//该变量为已被声明为全局变量
coprint(HT+start->
rchild,HT);
if(start->
lchild!
=NULL&
start->
rchild!
=NULL)t='
'
setw(5*numb)<
weight<
t<
fprintf(TreePrint,"
%d\n"
start->
weight);
cop
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 实验 报告 哈夫曼树 应用