数据结构课设赫夫曼树Word文档下载推荐.docx
- 文档编号:18531430
- 上传时间:2022-12-19
- 格式:DOCX
- 页数:20
- 大小:24KB
数据结构课设赫夫曼树Word文档下载推荐.docx
《数据结构课设赫夫曼树Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《数据结构课设赫夫曼树Word文档下载推荐.docx(20页珍藏版)》请在冰豆网上搜索。
60)
score=’不及格’;
elseif(x<
70)
score=’及格’;
80)
score=’中’;
90)
score=’良’;
else
score=’优’;
如果学生规模很大,该算法需反复多次执行,就应该考虑算法执行的时间问题。
在
实际应用中,学生的成绩呈正态分布,大部分在70~89分之间,优秀和不及格的概率较
小。
假设不及格、及格、中、良、优的百分比为5%、12%、40%、35%、8%,则上述算法
80%以上的成绩需要进行三次或三次以上的比较才能得到结果。
若以这些百分比值
5,12,40,35,8为权值,使用哈夫曼算法来构造一棵判定树,则得到判定过程,可使多数
成绩经过较少的比较即可得到结果。
但由于每个判定框都有两次比较,将两次比较分开,
得到判定树,按此判定树构造程序,显然可以大大减少比较次数。
2.1.3哈夫曼树在数据编码中的应用
在数据通信中,需要将传送的文字转换成二进制的字符串,用0,1码的不同排列
来表示字符。
例如,需传送的报文为“AFTERDATAEARAREARTAREA”,这里用到
的字符集为“A,E,R,T,F,D”,各字母出现的次数为{8,4,5,3,1,1}。
现要求
为这些字母设计编码。
要区别6个字母,最简单的二进制编码方式是等长编码,固定采
用3位二进制,可分别用000、001、010、011、100、101对“A,E,R,T,F,D”进行编码发送,当对方接收报文时再按照三位一分进行译码。
显然编码的长度取决报文中
不同字符的个数。
若报文中可能出现26个不同字符,则固定编码长度为5。
然而,传送报文时总是希望总长度尽可能短。
在实际应用中,各个字符的出现频度或使用次数是不
相同的,如A、B、C的使用频率远远高于X、Y、Z,自然会想到设计编码时,让使用频率高的用短码,使用频率低的用长码,以优化整个报文编码。
但这样长短不等的编码又
会产生一个新问题,即如何解译成原文?
除非设计时能够保证任何一个字符的编码都不是同一字符集中另一个字符的编码的前缀,符合此要求的编码称为前缀编码。
为使不等长编码为前缀编码,可用字符集中的每个字符作为叶子结点生成一棵编码二叉树,为了获得传送报文的最短长度,可将每个字符的出现频率作为字符结点的权值
赋予该结点上,求出此树的最小带权路径长度就等于求出了传送报文的最短长度。
因此,
求传送报文的最短长度问题转化为求由字符集中的所有字符作为叶子结点,由字符出现频率作为其权值所产生的哈夫曼树的问题。
利用哈夫曼树来设计二进制的前缀编码,既满足前缀编码的条件,又保证报文编码总长最短。
我们用上述各字母出现的次数{8,4,5,3,1,1}作为权构造哈夫曼树,如图6.36所示。
约定左分支表示字符“0”,右分支表示字符“1”,则可以从根结点到叶子结点的路径的分支上的字符组成的字符串作为该叶子对应字符的编码。
可以证明,如此得到的必为二进制前缀编码,而且是一种最优前缀编码。
我们称这样的树为哈夫曼编码树,
由此得到的编码称为哈夫曼编码。
本例中字母A、E、R、T、F、D的哈夫曼编码分别为11、00、01、011、0100、0101。
可以看出,出现次数较多的字母A、E、R,具有最短的
编码,长度均为2;
而出现次数最少的字母F、D,具有最长的编码,长度均为4。
报文
的最短传送长度为:
6
L=WPL=S(wklk)=4×
2+5×
2+8×
2+3×
3+1×
4+1×
4=51
k=1
若采用等长编码,报文的传送长度为
L=8×
3+4×
3+5×
3+3×
3=66
显然,哈夫曼编码比等长编码所得到的报文长度要短得多。
哈夫曼编码是最优前缀
编码。
一个任意长度的编码序列可被唯一地翻译为一个字符序列(单词)。
依次取出编码
序列中的0或1,从哈夫曼编码树的根结点开始寻找一条路径。
若为0,则沿着左分支
向下走;
若为1,则沿着右分支向下走。
每到达一个叶子外结点时,就译出一个相应的
字符,然后再回到哈夫曼树的根结点处,依次译出余下的字符,最后得到一个单词。
2.2数据结构设计
通过建立一个赫夫曼树的简易程序,可以实现建立最优二叉树函数,并且可以建立
函数输入二叉树,并输出其赫夫曼树。
此程序是线性链表式存储结构,这种存储结构便于数据的插入和删除,同时还节约
存储空间。
各种编码方式
(1)定长编码
根据出现的字符种数进行编码
(2)变长编码
采取这种变长编码方式,需要遵循一个原则,即每一个字符的编码都不应该是另一
个字符编码的前缀。
否则就会出现二义性。
一个可用的编码必须满足每个字符的编码不能是其他编码的前缀。
也可以看出,每一个可用的编码都可以转化成二叉树的形式,这样编码理论便可以
与二叉树的一些性质结合起来,就可以应用二叉树的理论知识来解决编码问题。
那么总的编码长度为:
WPL=w1*L1+w2*L2+w3*L3+w4*L4
可以看出,该公式与哈夫曼树满足的公式一模一样,那么我们可以采取构造哈夫曼
树的方式来求编码的长度。
对哈夫曼树进行编码,每一个结点的左分支上面标0,右分支上面标1,从根结点到
各个叶子结点,所经分支上面的0、1序列,就是该叶子结点所代表字符的编码。
假设有n个权值{w1,w2,wn},每个权值赋给一个叶子,可以构造出多棵含n个
叶子结点的二叉树。
其中,必存在一棵其带权路径长度WPL取最小值的二叉树,称为最
优二叉树。
因为构造这种树的算法最早是哈夫曼1952年提出来的,所以被称为哈夫曼树
(HuffmanTree)。
如何构造哈夫曼树?
D.A.Huffman最早研究出一个带有一般规律的构造算法,俗称哈夫曼算法,其基本思想是让权值最大的叶子离根最近。
构造方法如下:
(1)由给定的n个权值{w1,w2,,wn},构造n棵扩充二叉树的集合F={T1,
T2,,Tn},其中每棵扩充二叉树中均只含一个带权值wi的根结点,其左、右子树均
为空;
(2)重复下列步骤,直到F中只含一棵树为止:
j在F中选取其根结点的权值为最小的两棵扩充二叉树,分别作为左、右子树构造一棵新的二叉树,并置这棵新的二叉树根结点的权值为其左、右子树根结点的权值之和;
k从F中删去这两棵树,同时加入刚生成的新树;
(3)按上述步骤得到的二叉树就是哈夫曼树。
2.3设计思路及算法设计
2.3.1功能模块图
统
查
构
计
找
造
字
最
赫
符
小
夫
出
的
曼
现
两
树
个
并
频
权
输
率
图1功能模块图
2.3.2功能模块图思路设计
设需要编码的字符集合为{d1,d2,,dn},各个字符在电文中出现的次数集合为
{w1,w2,,wn},以d1,d2,,dn作为叶结点,以w1,w2,,wn作为各叶结点的
权值构造一棵二叉树,规定赫夫曼树中的左分支为0,右分支为1,则从根结点到每个
叶结点所经过的分支对应的0和1组成的序列便为该结点对应字符的编码。
这样的代码
总长度最短的不等长编码称为赫夫曼编码。
赫夫曼算法:
根据给定的n个权值{w1,w2,w3,wn}构成n棵二叉树的集合F={T1,T2,T3,Tn},其中每棵二叉树Ti中只有一个带权为Wi的根结点,其左右树均空。
在F中选取两棵根结点的权值最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为期左、右子树上根结点的权值之和。
在F中删除这棵树,同时将新得到的二叉树加入F中。
重复
(2)和(3)的过程,直到F只含一棵树为止。
设给定的权值集合为{5,4,7,2},构造哈夫曼树的过程如图6.34所示。
首先构
造每棵树只有一个结点的森林,如图2(a)所示;
然后每次选择两个根结点权值最小的二
叉树,以它们为左、右子树构造新的二叉树,步骤参看图2(b),(c)和(d),最后得到一
棵扩充二叉树
F:
{5},{4},{7},{2}F:
{5},{6},{7}
6
5472
2457
(a)初始(b)合并树{2}{4}后
{11},{7}F:
{18}
18
11
711
56
247
24
(c)合并树{5}{6}后(d)合并树{7}{11}后
图2哈夫曼树的构造过程
2.4详细设计
2.4.1程序流程图
开始
创建一个空的赫夫曼树
Y
判断PHt是否为空
N
输入m
判断m是否比1
输入外部结点
个数及权值
找两个最小权的无父结点的结
点构造新的二叉树N
得到新的结点
所有结点生成树
得到赫夫曼树编码
输出
结束
图3流程图
2.4.2算法设计
(1)建立最优二叉树函数
由于赫夫曼树种没有度为的结点(这类又称严格的(strict)(或正则的)二叉树),则
一颗有n个叶子结点的赫夫曼树共有2n-1个结点,可以存储在一个大小为2n-1的一维
数组中。
如何选定结点结构?
由于在构成赫夫曼树之后,为求编码需要从叶子结点出发
走一条从叶子到根的路径;
而为译码需要从根出发走一条从根到叶子的路径。
则对每个
节点而言,既需知双亲的信息,又需知孩子结点的信息。
由此:
二叉树的存储结构:
#defineMAXINT2147483647
#defineMAXNUM50/*数组w中最多容纳的元素个数,注意m<
=MAXNUM*/
#defineMAXNODE100/*哈夫曼树中的最大结点数,注意2*m-1<
MAXNODE*/
structHtNode{/*哈夫曼树结点的结构*/
intww;
intparent,llink,rlink;
};
(2)赫夫曼树的构造算法
根据给定的n个权值{w1,w2,w3,wn}构成n棵二叉树的集合F={T1,T2,
T3,Tn},其中每棵二叉树Ti中只有一个带权为Wi的根结点,其左右树均空。
在F中选取两棵根结点的权值最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为其左、右子树上根结点的权值之和。
重复操作直到所有结点生成
树。
PHtTreehuffman(intm,int*w)
{
PHtTreepht;
inti,j,x1,x2,m1,m2;
pht=(PHtTree)malloc(sizeof(structHtTree));
/*创建空哈夫曼树*/
if(pht==NULL)
printf("
Outofspace!
!
\n"
);
returnpht;
}
for(i=0;
i<
2*m-1;
i++)
{/*置初态*/
pht->
ht[i].llink=-1;
ht[i].rlink=-1;
ht[i].parent=-1;
if(i<
m)
ht[i].ww=w[i];
ht[i].ww=-1;
for(i=0;
m-1;
i++){/*每循环一次构造一个内部结点*/
m1=MAXINT;
m2=MAXINT;
/*相关变量赋初值*/
x1=-1;
x2=-1;
for(j=0;
j<
m+i;
j++)/*找两个最小权的无父结点的结点*/
if(pht->
ht[j].ww<
m1&
&
pht->
ht[j].parent==-1)
m2=m1;
x2=x1;
m1=pht->
ht[j].ww;
x1=j;
elseif(pht->
m2&
m2=pht->
x2=j;
ht[x1].parent=m+i;
/*构造一个内部结点*/
ht[x2].parent=m+i;
ht[m+i].ww=m1+m2;
ht[m+i].llink=x1;
ht[m+i].rlink=x2;
root=m+i;
(3)字符的赫夫曼编码的算法
向量HT的前n个分量表示叶子结点,最后一个分量表示根结点。
各字符的编码长
度不等,所以按实际长度分配空间。
求每个字符的赫夫曼编码是从叶子到根的逆向处理。
也可以从根出发遍历整棵赫夫曼树,求得各叶子结点所表示的字符的赫夫曼编码。
算法
如下:
intmain()
intm=0,j=0,i=0,parent=0;
int*w;
pleaseinputm="
/*输入外部结点个数*/
scanf("
%d"
&
m);
if(m<
1)
misnotreasonable!
\n"
return1;
w=(int*)malloc(sizeof(int)*m);
if(w==NULL)
overflow!
pleaseinputthe%dnumbers:
m);
/*输入权值*/
m;
j++)
w+j);
pht=huffman(m,w);
for(j=0;
theReversecodeofthe%dnodeis:
"
j+1);
/*得到的编码应倒过来*/
i=j;
while(pht->
ht[i].parent!
=-1){
parent=pht->
ht[i].parent;
ht[parent].llink==i)
0"
1"
i=parent;
return0;
(4)查找权值最小的两个结点的函数
选择二叉树的根结点,使达最小构造次优二叉树的算法,首先标价所有结点,依次
编号,判断结点的权值的大小,将所判断的结点赋值给一个变量,然运用比较算法,选
择权值较小的一个结点,赋值给的变量不变,另一个变量释放其所赋的值。
应用循环语
句进行新的赋值,继续比较,直到所有结点比较完毕。
s1、s2所有值就是全职最小的
两个结点。
依此算法比较完全部的结点由此构成一颗赫夫曼树。
算法如下:
voidSelect(HuffmanTreeHT,intn,int&
s1,int&
s2)
unsignedintweight;
inti;
s1=0;
s2=0;
weight=100;
for(i=1;
i<
=n;
i++)
if(HT[i].parent==0)
if(HT[i].weight>
weight)
continue;
weight=HT[i].weight;
s1=i;
HT[s1].parent=s1;
//暂时改写HT[s1].parent的值
s2=i;
2.5设计程序
#include<
stdlib.h>
stdio.h>
#defineMAXNUM50
#defineMAXNODE100
structHtNode{
structHtTree{
introot;
structHtNodeht[MAXNODE];
typedefstructHtTree*PHtTree;
if(pht==NULL){
i++){
m1=MAXINT;
m2=MAXINT;
x1=-1;
x2=-1;
j<
if(pht->
ht[j].parent==-1){
m1=pht->
intmain(){
&
1){
if(w==NULL){
for(j=0;
j++){
j+1);
3课程设计运行结果与分析
程序运行结果,初始操作界面如图4所示。
图4初始操作界面
输入字符6,显示操作界面如图5所示。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课设赫夫曼树