哈弗曼编码译码器Word文档下载推荐.docx
- 文档编号:16715766
- 上传时间:2022-11-25
- 格式:DOCX
- 页数:29
- 大小:133.08KB
哈弗曼编码译码器Word文档下载推荐.docx
《哈弗曼编码译码器Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《哈弗曼编码译码器Word文档下载推荐.docx(29页珍藏版)》请在冰豆网上搜索。
4.5对字符串进行编码12
4.5.1构造思想12
4.5.2字符串编码函数13
4.6将权值数据存放在数据文件(文件名为data.txt中)的程序18
5调试分析19
5.1输出huffman编码,即空格和26个大写字母的界面。
19
5.2对字符串进行编码的界面19
5.3将权值数据存放在数据文件(文件名为data.txt)的界面19
6总结20
参考文献21
附录源代码22
1项目研究背景与意义
1.1项目研究背景
在科技飞速发展的今天,信息传输显得尤为重要,这主要体现在计算机之间的数据传输,主要包括文字,声音,图像,视频等文件的传输,而计算机不能直接处理这些信息,计算机只能识别二进制数据。
例如文字,在数据通讯中,传送方要将传送的文字转换成由二进制字符0、1组成的二进制串,而接受方要将二进制字符0、1组成的二进制串还原成对应的文字形式。
于是便完成了文字数据的传输过程。
时下,数据结构是一门随着计算机科学的发展而逐渐形成的新兴学科。
随着计算机技术的发展,计算机的应用领域从最初的科学计算发展到人类社会的各个领域,计算机处理的对象也由纯粹的数值发展到字符、表格、图像和声音等各种具有一定结构的数据,这就给程序设计带来一些新的问题。
与飞速发展的计算机硬件相比,计算机软件的发展相对缓慢。
研究数据结构可以解决计算机之间的数据传输效率低下的问题。
在数据结构中,研究树形结构对数据编码有很大作用,对数据构造二叉树编码应用广泛。
1.2项目研究意义
本设计旨在解决数据通讯中传输字符过长的问题,哈夫曼编码能很好地解决这个问题。
哈夫曼编码是根据哈夫曼算法够造的哈夫曼树所得到的,哈夫曼算法使得编码总长度最小。
哈夫曼编码的理论依据是变长编码理论,将使用次数多的代码转换成长度较短的代码,而是用次数少的可以使用较长的编码,并且保持编码的唯一可解性。
利用哈夫曼编码进行信息通讯可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
2需求分析
2.1设计要求与分析
在当今信息爆炸时代,如何采用有效的数据压缩技术节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视,哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。
哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。
哈夫曼树中从根到每个叶子都有一条路径,对路径上的各分支约定:
指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个叶子对应的字符的编码,这就是哈夫曼编码。
假设每种字符在字符中出现的次数为Wi,编码长度为Li,字符中有n种字符,则字符编码总长为WiLi。
若将此对应到二叉树上,Wi为叶节点的权,Li为根节点到叶节点的路径长度。
那么,WiLi恰好为二叉树上带权路径长度。
2.2基本要求
设计一个利用哈夫曼算法的编码和译码系统,重复地显示并处理以下项目,直到选择退出为止。
1将权值数据存放在数据文件(文件名为data.txt,位于执行程序的当前目录中)
2采用静态存储结构
3初始化:
键盘输入字符集大小n、n个字符和n个权值,建立哈夫曼树;
4编码:
利用建好的哈夫曼树生成哈夫曼编码;
5输出编码;
6设字符集及频度如下表:
字符空格ABCDEFGHIJKLM
频度1866413223210321154757153220
字符NOPQRSTUVWXYZ
频度5763151485180238181161
3概要设计
3.1系统功能模块图
图3-1系统功能模块图
3.2主要功能函数
main函数中调用了5个主要功能函数,即
1建立huffuman树函数:
voidsethfmtree()
2找权值最小的2个结点函数:
voidselect(ints);
3建立huffman编码函数:
voidsethfmcode()
4输出huffman编码函数:
voidprinthfmcode()
5对字符串进行编码函数:
voidsetcode()
其函数调用关系如图3-2所示。
图3-2函数调用关系图
4详细设计
4.1数据结构的定义
4.1.1宏定义
1定义了N为27,表示27个字符,即空格和26个大写字母
#defineN27
2定义了M为2*N-1,表示huffman树的结点个数
#defineM2*N-1
3定义了maxnumber为一个很大的数
#definemaxnumber10000
4.1.2huffman树的结点结构
structnode
{
intweight;
//结点权值
intparent,lchild,rchild;
//双亲,左孩子,右孩子
};
4.1.3huffman编码结构
structcodetype
intstart;
//起始位置
charcodes[N+1];
//存放哈夫曼编码的数组
4.1.4字符及其编码的结构
structelement
charcharacter;
//字符
structcodetypecode;
//字符编码
4.2建立哈夫曼树
4.2.1基本原理
哈夫曼在上世纪五十年代初提出这种编码时,根据字符出现的概率来构造平均长度最短的编码。
它是一种变长的编码。
在编码中,若各码字长度严格按照码字所对应符号出现概率的大小的逆序排列,则编码的平均长度是最小的。
(注:
码字即为符号经哈夫曼编码后得到的编码,其长度是因符号出现的概率而不同,所以说哈夫曼编码是变长的编码。
)
一般而言,给定n个实数w1,w2,......,wn(n≥2),求一个具有n个结点的二叉数,使其带权路径长度最小。
所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。
树的带权路径长度记为WPL=(W1*L1+W2*L2+W3*L3+...+Wn*Ln),N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n)。
可以证明哈夫曼树的WPL是最小的。
4.2.2构造思想
由哈夫曼算法的定义可知,初始森林中共有n棵只含有根节点的二叉树。
算法的第二步是:
将当前森林中的两棵根节点权值最小的二叉树,合并成一棵新的二叉树;
每合并一次,森林中就减少一棵树,产生一个新结点。
显然要进行n-1次合并,所以共产生n-1个新结点,它们都是具有两个孩子的分支结点。
由此可知,最终求得的哈夫曼树中一共有2n-1个结点,其中n个叶节点是初始森林的n个孤立节点。
并且哈夫曼树中没有度数为1的分支结点。
我们可用一个大小为2n-1的一维数组来存储哈夫曼树中的结点。
要实现哈夫曼树算法,首先要实现在hfmcodes[N+1]中选择parent为0且权值最小的两个根结点的选择算法。
4.2.3具体构造方法
1首先根据给定的权值构造n棵二叉树的森林,其中每个二叉树都只有一个权值为treeweight[i]的根节点
2在森林中选取两个权值最小的根节点作为一个新二叉树的左右结点
其具体函数为:
voidselect(ints)//找权值最小的2个结点
inti;
intv1,v2;
v1=v2=maxnumber;
x1=x2=0;
for(i=1;
i<
=s;
i++)
if(tree[i].parent==0)
if(tree[i].weight<
v1)
{
v2=v1;
x2=x1;
v1=tree[i].weight;
x1=i;
}
elseif(tree[i].weight<
v2)
v2=tree[i].weight;
x2=i;
通过遍历所有节点找到权值最小的结点
3设新二叉树的根节点为左右子结点的权值和其函数表达为
for(i=N+1;
=M;
i++)//找权值最小的2个结点,组成huffman树
select(i-1);
//调用找权值最小的2个结点函数
tree[x1].parent=i;
tree[x2].parent=i;
tree[i].lchild=x1;
tree[i].rchild=x2;
tree[i].weight=tree[x1].weight+tree[x2].weight;
4从森林中删除选中的那两棵二叉树,同时加入新构造的那个二叉树
5重复上述步骤,得到所需的哈夫曼二叉树
4.2.4建立huffuman树函数
voidsethfmtree()//建立huffuman树
inti,j;
inttreeweight[N]={186,63,13,22,32,103,21,15,47,57,1,5,32,20,57,63,15,1,48,51,80,23,8,18,1,16,1};
charhfmcodesch[N]=
{'
'
'
A'
B'
C'
D'
E'
F'
G'
H'
I'
J'
K'
L'
M'
N'
O'
P'
Q'
R'
S'
T'
U'
V'
W'
X'
Y'
Z'
i++)//初始化双亲,左右孩子结点为0
tree[i].parent=tree[i].lchild=tree[i].rchild=0;
=N+1;
i++)//初始化27个字符及其权值
hfmcodes[i].ch=hfmcodesch[i-1];
//hfmcodes[N+1]n个结点的huffman编码表
tree[i].weight=treeweight[i-1];
}
v2=v1;
4.3建立huffman编码
4.3.1构造思想
给定字符集的哈夫曼树生成后,求哈夫曼编码的具体实现过程是:
依次以叶子为出发点,向上回溯至根为止。
上溯时走左分支则生成代码0,走右分支则生成代码1。
4.3.2建立huffman编码函数
voidsethfmcode()
inti,s,f,k=1;
structcodetypec;
=N;
c=hfmcodes[i].code;
c.start=N+1;
s=i;
f=tree[s].parent;
do
c.start--;
if(s==tree[f].lchild)
c.codes[c.start]='
0'
;
else
1'
s=f;
}while(f);
hfmcodes[i].code=c;
4.4输出huffman编码函数
voidprinthfmcode()//输出huffman编码,即空格和26个大写字母
printf("
哈夫曼的编码为:
\n"
);
%c:
"
hfmcodes[i].character);
for(j=c.start;
j<
j++)
%c"
c.codes[j]);
\n\n--------------------------------------------------------------------\n\n"
4.5对字符串进行编码
4.5.1构造思想
①由于生成的编码与要求的编码反序,将生成的代码先从后往前依次存放在一个临时向量中,并设一个指针start指示编码在该向量中的起始位置(start初始时指示向量的结束位置)。
②当某字符编码完成时,从临时向量的start处将编码复制到该字符相应的位串hfmchars中即可。
③因为字符集大小为n,故变长编码的长度不会超过n,加上一个结束符'
\0'
,hfmchars的大小应为n+1。
4.5.2字符串编码函数
voidsetcode()//对字符串进行编码
inti,j,count;
charc0,k='
while(k=='
)//利用循环,实现对字符串多次编码
\n\n请输入字符串(大写字母和空格,不多于1000个字符),输入'
.'
(+回车)号结束\n\n"
=100;
i++)//利用循环,实现对字符串输入
c0=getchar();
t[i].character=c0;
if(c0=='
)break;
count=i;
//记录字符串个数
\n\n字符串编码为:
\n\n"
=count;
i++)//利用循环,实现对字符串输出
if(t[i].character=='
)break;
switch(t[i].character)//利用开关语句,查找编码
case'
:
c=hfmcodes[1].code;
j++)//输出编码
%C"
"
break;
c=hfmcodes[2].code;
c=hfmcodes[3].code;
c=hfmcodes[4].code;
c=hfmcodes[5].code;
c=hfmcodes[6].code;
for(j=c.start;
printf发
c=hfmcodes[14].code;
c=hfmcodes[15].code;
c=hfmcodes[16].code;
c=hfmcodes[17].code;
c=hfmcodes[18].code;
c=hfmcodes[19].code;
c=hfmcodes[20].code;
case'
c=hfmcodes[21].code;
c=hfmcodes[22].code;
c=hfmcodes[23].code;
c=hfmcodes[24].code;
c=hfmcodes[25].code;
c=hfmcodes[26].code;
c=hfmcodes[27].code;
default:
*此编码找不到,请检查输入是否正确*"
\n\n\n--------------------------------------------------------------------\n\n"
\n\n\n-----是否继续?
?
(Y/N)Y表示继续,N表示不继续-----\n"
getchar();
scanf("
&
k);
\n\n*********************************************************\n\n"
4.6将权值数据存放在数据文件(文件名为data.txt中)的程序
5调试分析
图5-1输出huffman编码
5.2对字符串进行编码的界面
图5-2字符串编码
5.3将权值数据存放在数据文件(文件名为data.txt)的界面
图5-3存放数据文件(文件名为data.txt)
6总结
参考文献
[1]严蔚敏.数据结构.C语言版.清华大学出版社.2013
[2]严蔚敏等.数据结构题集.C语言版.清华大学出版社.2013
[3]曲建民,刘元红,郑陶然.数据结构.C语言版.清华大学出版社.
2005
[4]李春葆编著.数据结构教程.清化大学出版社.2005
[5]蒋立翔编著.C++程序设计技能百练.中国铁道出版社.2004
附录源代码
#include<
string.h>
stdio.h>
stdlib.h>
#defineN27//空格和26个大写字母
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 哈弗曼 编码 译码器