哈夫曼树的建立及哈弗曼编码的构造Word下载.docx
《哈夫曼树的建立及哈弗曼编码的构造Word下载.docx》由会员分享,可在线阅读,更多相关《哈夫曼树的建立及哈弗曼编码的构造Word下载.docx(14页珍藏版)》请在冰豆网上搜索。
![哈夫曼树的建立及哈弗曼编码的构造Word下载.docx](https://file1.bdocx.com/fileroot1/2022-10/28/82402fc9-cec4-4be7-b249-abcc85957b00/82402fc9-cec4-4be7-b249-abcc85957b001.gif)
5程序运行结果⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯----⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯10
6.实验总结⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯13
1.实验目的
掌握哈夫曼树的建立及哈夫曼编码的生成方法;
首先输入字符和对应的权值,打印输出哈夫曼树和字符的编码;
然后输入一字符串,对其进行编码;
最后输入由0、1组成的字符串,实现对其的译码!
2.问题描述
利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
这要求在发送端通过一个编码系统对待传输数据预先编码,在接收端将传来的数据进行译码(复原)。
对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。
试为这样的信息收发站编写一个赫夫曼码的编/译码系统。
用下表给出的字符集和频度的实际统计数据建立哈夫曼树,并实现以下报文的编码和译码:
“THISPROGRAMISMYFAVORITE”。
字符
空格
A
B
C
D
E
F
G
H
I
J
K
L
M
频度
186
64
13
22
32
103
21
15
47
57
1
5
20
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
63
48
51
80
23
8
18
16
3.算法的思想与算法实现步骤
1)主要思想:
根据给定的字符和其中每个字符的频度,构造哈夫曼树,并输出字符集中每个字符的哈夫曼编码.将给定的字符串根据其哈夫曼编码进行编码,并进行相应的译码.
2)基本框架:
函数名
属性
功能
inithfmt(hfmtt)
t[i].weight=0;
t[i].lchild=-1;
t[i].rchild=-1;
t[i].parent=-1;
对结构体htnode初始化,实现父子结点的初始值
inputweight(hfmtt)/
intw;
//w权值chark;
//字符
t[i].key=k;
t[i].weight=w;
自定义输入函数,输入对应的字符和权值。
selectmin(hfmtt,inti,int*p1,int*p2)
longmin1=999999;
longmin2=999999;
每次选权值最小、次小的结点使之成为新结点。
creathfmt(hfmtt)
t[i].lchild=p1;
t[i].rchild=p2;
t[i].weight=t[p1].weight+t[p2].weight;
创建哈夫曼树的函数
printhfmt(hfmtt)
printf("
\t\t权值\t父母\t左孩子\t右孩子\t字符\t"
);
打印哈夫曼树
hfmtpath(hfmtt,inti,intj)
hfmtpath(t,i,j);
if(t[b].lchild==a)printf("
0"
elseprintf("
1"
哈夫曼树编码路径的递归算法.
phfmnode(hfmtt)
\t\t%c\t"
t[i].key,t[i].weight);
hfmtpath(t,i,j);
对字符进行初始编码
encoding(hfmtt)
if(r[j]==t[i].key)hfmtpath(t,i,j);
对输入的电文进行编码
decoding(hfmtt)
j=2*n-2;
//j从树的根节点开始
对用户输入的密文进行
intmain()
hfmtht;
charflag;
主菜单输出
3)系统结构图(功能模块图)
4.程序核心代码及主要设计
1.哈夫曼树节点的数据类型定义:
代码:
typedefstruct
{
intweight;
intlchild;
intrchild;
intparent;
charkey;
}htnode;
2、voidinithfmt(hfmtt)初始化哈夫曼树,处理inputweight(hfmtt)函数得到的数据,按照哈夫曼规则建立2叉树。
此函数块调用了selectmin()函数。
代码:
voidinithfmt(hfmtt)//对结构体进行初始化
inti;
printf("
\n请输入要设置的叶子结点个数n="
scanf("
%d"
&
n);
getchar();
for(i=0;
i<
2*n-1;
i++)//对结构体进行初始化
{
t[i].weight=0;
t[i].lchild=-1;
t[i].rchild=-1;
t[i].parent=-1;
}
\n"
}
voidinputweight(hfmtt)//输入函数
intw;
//w表示权值
chark;
//k表示获取的字符
n;
i++)
{
请输入第%d个字符:
"
i+1);
%c"
k);
t[i].key=k;
请输入第%d个字符的权值:
w);
}}
3、selectmin(hfmtt,inti,int*p1,int*p2)//Select函数,选出t树到a为止,权值最小且parent为0的2个节点.
代码:
voidselectmin(hfmtt,inti,int*p1,int*p2)//选中两个权值最小的函数
longmin1=999999;
intj;
for(j=0;
j<
=i;
j++)//选择最小权值字符的下标返回
if(t[j].parent==-1)
if(min1>
t[j].weight)
min1=t[j].weight;
*p1=j;
}
j++)//选择次小权值字符的下标还回
if(min2>
t[j].weight&
&
j!
=(*p1))//注意j!
=(*p1))
min2=t[j].weight;
*p2=j;
}}
4、创建哈夫曼树的函数
voidcreathfmt(hfmtt)//
inti,p1,p2;
inithfmt(t);
inputweight(t);
for(i=n;
selectmin(t,i-1,&
p1,&
p2);
t[p1].parent=i;
t[p2].parent=i;
t[i].lchild=p1;
t[i].rchild=p2;
t[i].weight=t[p1].weight+t[p2].weight;
}}
5、打印输出哈夫曼树,字符,权值,以及它对应的编码
voidprinthfmt(hfmtt)
*******由哈夫曼编码建立的图表结构如下:
*******\n"
\t\t%d\t%d\t%d\t%d\t%c"
t[i].weight,t[i].parent,t[i].lchild,t[i].rchild,t[i].key);
\n\n"
6、编码的重要哈夫曼树路径递归算法
voidhfmtpath(hfmtt,inti,intj)
inta,b;
a=i;
b=j=t[i].parent;
if(t[j].parent!
=-1)
{i=j;
hfmtpath(t,i,j);
if(t[b].lchild==a)
else
7、对字符进行初始编码
voidphfmnode(hfmtt)//
{
inti,j,a;
***所得哈夫曼编码为***\n"
j=0;
8、encoding
编码功能:
对输入字符进行编码
voidencoding(hfmtt)//对用户输入的电文进行编码
charr[1000];
//用来存储输入的字符串
inti,j;
\n\n请输入需要编码的字符:
gets(r);
编码结果为:
r[j]!
='
\0'
;
j++)
if(r[j]==t[i].key)
9、decoding
译码功能:
输入0-1字符组成的字符串,然后对其解码输出对应的字符!
voiddecoding(hfmt