数据结构课程设计报告文档格式.docx
- 文档编号:16307989
- 上传时间:2022-11-22
- 格式:DOCX
- 页数:19
- 大小:313.93KB
数据结构课程设计报告文档格式.docx
《数据结构课程设计报告文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计报告文档格式.docx(19页珍藏版)》请在冰豆网上搜索。
2、算法实现7
六、程序测试与实现12
1、主程序12
2、测试数据13
3、测试结果14
生成哈夫曼树运行结果图:
14
哈夫曼编码运行结果图:
15
编码函数运行结果图:
译码函数运行结果图:
平均编码长度函数运行结果图:
七、调试分析15
程序调试的步骤:
调试体会:
16
八、遇到的问题及解决办法16
九、心得体会16
一、问题描述(内容格式参考下面的描述,以下类似)
利用哈夫曼编码进行信息通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
但是,这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码(复原)。
试写一个哈夫曼编/译码系统。
一个完整的系统应具有以下功能:
(1)初始化。
从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件中。
(2)编码。
利用已建好的哈夫曼树对文件中的正文进行编码,然后将结果存入文件中。
(3)译码。
利用已建好的哈夫曼树将文件中的代码进行译码,结果存入文件中。
(4)完成数据测试,要求编码字符不低于15个,编码文件的长度不低于50个字符。
(5)计算平均编码长度。
二、需求分析
2.1设计目标
1)初始化(Initialization)。
从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件Tree.out中。
输出哈夫曼树,及各字符对应的编码。
2)输入(Input)。
从终端读入需要编码的字符串s,将字符串s存入文件Orinigal.txt中。
3)编码(Encode)与译码(Decode)。
编码(Encode)。
利用已建好的哈夫曼树(如不在内存,则从文件Tree.out中读入),对文件Orinigal.txt中的正文进行编码,然后将结果存入文件CodeOrinigal.txt中。
译码(Decode)。
利用已建好的哈夫曼树将文件CodeOrinigal.txt中的代码进行译码,结果存入文件TextFile中。
输出编码文件(Print)。
将编码显示在终端上。
同时将此字符形式的编码写入文件Code.out中。
4)打印哈夫曼树(TreePrinting)。
将已在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件Tree.out中。
5)计算编码平均长度。
计算编码平均长度,并显示在屏幕上。
2.2设计思想
哈夫曼编码(HuffmanCoding)是一种编码方式,以哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。
是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。
这种方法是由David.A.Huffman发展起来的。
例如,在英文中,e的出现概率很高,而z的出现概率则最低。
当利用哈夫曼编码对一篇英文进行压缩时,e极有可能用一个位(bit)来表示,而z则可能花去25个位(不是26)。
用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个位。
二者相比,e使用了一般编码的1/8的长度,z则使用了3倍多。
倘若我们能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。
三、概要设计
3.1程序结构
程序从文件data.in中获取26个英文字母以及对应的权值。
(1)对输入的一段欲编码的字符串进行统计各个字符出现的次数,并它们转化为权值{w1,w2,……,wN}构成n棵二叉树的集合F={T1,T2,……,Tn}把它们保存到结构体数组HT[n]中,其中{Ti是按它们的ASCⅡ码值先后排序。
其中每棵二叉树Ti中只有一个带权为Wi的根结点的权值为其左、右子树上根结点的权值之和。
(2)在HT[1..i]中选取两棵根结点的权值最小且没有被选过的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为左、右子树上根结点的权值之和。
(3)哈夫曼树已经建立后,从叶子到根逆向求每一个字符的哈夫曼编码。
译码的过程是分解电文中字符串,从根出发,按字符'
0'
或'
1'
确定找左孩子或右孩子,直至叶子结点,便求的该子串相应字符并输出接着下一个字符。
四、数据结构设计
1.元素类型,结点类型,指针类型
structelement//哈夫曼树结点
{
chardata;
//数据域
intweight;
//权值
intlchild,rchild,parent;
//左孩子右孩子,父结点
intflag;
};
structCode//编码
intbit[MaxSize];
//编码
intstart;
//开始位置
structEncode//编码
stringcode;
//编码对应的值
intw[MaxSize];
//存放权值的数组
intn;
//n个字符
introot;
//根结点
CodeHuffCode[MaxCode];
//哈夫曼编码数组
Encodeencode[MaxSize];
//编码数组
elementhuffmanTree[MaxSize];
//哈夫曼树结点
2.包含的函数
Huffman();
~Huffman(){}
voidHuffmanTree();
//建立哈夫曼树
voidInitialization();
//初始化程序
voidPrintHuffman(elementH[],elementHH,intn);
//打印哈夫曼树
voidHuffmanCode();
//生成哈夫曼编码
voidPrintCode();
//打印哈夫曼编码
voidFileCode();
//文件输出哈夫曼编码
voidFileHuffman(elementH[],elementHH,intn);
//文件输出哈夫曼树
intgetRoot(){returnroot;
}//获取根结点
voidCode_length();
//计算平均编码长度
voidEnCode();
//为文件编码
voidReadCode();
//读取字符以及对应的哈夫曼编码
voidDecode();
//为编码文件译码
五、算法设计
1、算法分析(必须要用语言进行描述)
哈夫曼树
给定n个权值作为n的叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffmantree)。
哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
哈夫曼树的构造
一、对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F={T1,T2,T3,...,Ti,...,Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。
(为方便在计算机上实现算法,一般还要求以Ti的权值Wi的升序排列。
)
二、在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。
三、从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。
四、重复二和三两步,直到集合F中只有一棵二叉树为止。
哈夫曼编码
哈夫曼编码(HuffmanCoding)是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。
Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。
哈夫曼编码步骤:
哈夫曼树已经建立后,从叶子到根逆向求每一个字符的哈夫曼编码。
哈夫曼编码平均编码长度:
哈夫曼编码平均编码长度=每个字符的权值和该字符对应的哈夫曼编码的长度的乘积的和/权值的总和。
2、算法实现
1.哈夫曼树的建立:
voidHuffman:
:
HuffmanTree()//建立哈夫曼树
inti1,i2,m1,m2;
for(inti=0;
i<
2*n-1;
i++)//初始化哈夫曼树
{
if(i<
n)huffmanTree[i].weight=w[i];
else
huffmanTree[i].weight=0;
huffmanTree[i].data='
/'
;
}
huffmanTree[i].parent=-1;
huffmanTree[i].lchild=-1;
huffmanTree[i].rchild=-1;
huffmanTree[i].flag=0;
n-1;
i++)
m1=m2=MaxValue;
i1=i2=0;
for(intj=0;
j<
n+i;
j++)
if(huffmanTree[j].weight<
m1&
&
huffmanTree[j].flag==0)//查找最小权值m1和标号为x1;
m2和x2为此最小
m2=m1;
i2=i1;
m1=huffmanTree[j].weight;
i1=j;
elseif(huffmanTree[j].weight<
m2&
huffmanTree[j].flag==0)
m2=huffmanTree[j].weight;
i2=j;
huffmanTree[i1].flag=1;
huffmanTree[i2].flag=1;
huffmanTree[n+i].weight=huffmanTree[i1].weight+huffmanTree[i2].weight;
huffmanTree[i1].parent=n+i;
huffmanTree[i2].parent=n+i;
huffmanTree[n+i].lchild=i1;
huffmanTree[n+i].rchild=i2;
}
2.哈夫曼编码
HuffmanCode()//哈夫曼编码函数
Codecd[MaxCode];
inti,j,child,parent;
for(i=0;
n;
cd->
start=n-1;
weight=huffmanTree[i].weight;
child=i;
parent=huffmanTree[child].parent;
while(parent!
=-1)//从叶子出发到根逆序得出哈夫曼编码
if(huffmanTree[parent].lchild==child)
bit[cd->
start]=0;
start]=1;
start--;
child=parent;
for(j=cd->
start+1;
HuffCode[i].bit[j]=cd->
bit[j];
HuffCode[i].start=cd->
HuffCode[i].weight=cd->
weight;
root=child;
3.编码函数
EnCode()//编码函数
stringen[100];
intpos=0,j;
intflag=0;
charOriginal[MaxChar];
memset(Original,0,MaxChar);
ifstreamifile;
//从文件中读取出原文
ifile.open("
Original.in"
);
while(!
ifile.eof())
ifile>
>
Original[pos];
pos++;
ifile.close();
cout<
<
"
原文如下:
"
<
Original<
endl;
//s=newstring[pos];
for(inti=0;
i++)//遍历得出文件中字符对应的哈夫曼编码
for(j=0;
pos;
if(Original[j]==encode[i].data)
en[j]=encode[i].code;
flag++;
if(flag==pos)
break;
ofstreamofile;
ofile.open("
CodeOriginal.out"
//将编译以后的编码写入文件中
cout<
经过编译后的字符串:
for(intj=0;
ofile<
en[j];
endl;
4.译码函数
Decode()
intpos=0,p=0,f=0;
stringt;
charenco[10000];
chartmp[50]={'
\0'
memset(tmp,0,50);
enco[p];
p++;
译文如下:
for(inti=pos;
p;
tmp[f]=enco[i];
t=tmp;
if(t==encode[j].code)
encode[j].data;
pos=i+1;
f=-1;
f++;
5.求平均编码长度
Code_length()
doubleres;
doublesumWeight=0,Codelength=0;
doublenum=0;
sumWeight=sumWeight+w[i];
num=0;
for(intj=HuffCode[i].start;
num++;
Codelength=Codelength+num*w[i];
res=Codelength/sumWeight;
res<
3、算法流程图
六、程序测试与实现
1、主程序
voidmenu()
**************************************************************"
cout<
*哈夫曼编译码器*"
*1.初始化程序*"
*2.编码*"
*3.译码*"
*4.计算编码平均长度*"
*5.退出*"
***************************************************************"
intmain()
menu();
HuffmanH;
intchoose;
for(;
请选择要执行的功能:
cin>
choose;
switch(choose)
case1:
H.Initialization();
H.HuffmanTree();
H.HuffmanCode();
各字符编码如下:
H.PrintCode();
H.FileCode();
哈夫曼树如下:
H.PrintHuffman(H.huffmanTree,H.huffmanTree[H.getRoot()],0);
H.FileHuffman(H.huffmanTree,H.huffmanTree[H.getRoot()],0);
文件已保存为Tree.out!
case2:
H.ReadCode();
H.EnCode();
case3:
H.Decode();
case4:
平均编码长度为:
H.Code_length();
default:
if(choose==5)
2、测试数据
ch=AWeight=64
ch=BWeight=13
ch=CWeight=22
ch=DWeight=32
ch=EWeight=143
ch=FWeight=21
ch=GWeight=15
ch=HWeight=41
ch=IWeight=57
ch=JWeight=12
ch=KWeight=5
ch=LWeight=1
ch=MWeight=20
ch=NWeight=57
ch=OWeight=66
ch=PWeight=15
ch=QWeight=1
ch=RWeight=48
ch=SWeight=51
ch=TWeight=80
ch=UWeight=23
ch=VWeight=8
ch=WWeight=18
ch=XWeight=120
ch=YWeight=16
ch=ZWeight=1
3、测试结果
七、调试分析
1)对各个模块函数进行单元调试,并测试模块间参数的传递与调用。
2)调试主函数和对其他模块函数的调用,并检验最后的输出结果。
1)对Huffman编码有了一个很好的认识,通过对Huffman编码的实现,对Huffman编码有了具体的认识和实践,对二叉树又有了一个更新的认识。
对文件有了一定的认识,可以进行简单的文件流操作。
2)算法的时间复杂度分析:
程序部分用双循环嵌套结构,所以时间复杂度为O(n2).
3)算法的空间复杂度分析:
算法的空间复杂度为O(n)。
八、遇到的问题及解决办法
程序运用了C++语言以及数据结构的核心思想,由于程序本身比较复杂,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)