数据结构huffman课程设计报告.docx

上传人:b****4 文档编号:12077129 上传时间:2023-04-16 格式:DOCX 页数:14 大小:109.86KB
下载 相关 举报
数据结构huffman课程设计报告.docx_第1页
第1页 / 共14页
数据结构huffman课程设计报告.docx_第2页
第2页 / 共14页
数据结构huffman课程设计报告.docx_第3页
第3页 / 共14页
数据结构huffman课程设计报告.docx_第4页
第4页 / 共14页
数据结构huffman课程设计报告.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

数据结构huffman课程设计报告.docx

《数据结构huffman课程设计报告.docx》由会员分享,可在线阅读,更多相关《数据结构huffman课程设计报告.docx(14页珍藏版)》请在冰豆网上搜索。

数据结构huffman课程设计报告.docx

数据结构huffman课程设计报告

数据结构课程设计报告

题目:

哈夫曼编/译码器

院(系):

计算机工程学院

专业:

计算机科学与技术

班级:

嵌入式1091

学生:

张楠楠

指导教师:

寇海洲孙成富

邱军林殷路

 

2010年12月

目录

1实验目的2

2概要设计2

2.1总体功能结构2

2.2数据结构设计4

2.3方法及原理5

3详细设计和实现6

3.1创建Huffman树6

3.2编码9

3.3译码11

4调试与操作说明13

总结16

1实验目的

设计一个利用哈夫曼算法的编码和译码系统,重复地显示并处理以下项目,直到选择退出为止。

【基本要求】

(1)初始化:

键盘输入字符集大小n、n个字符和n个权值,建立哈夫曼树;

(2)编码:

利用建好的哈夫曼树生成哈夫曼编码;

(3)输出编码;

(4)译码功能;

(5)设字符集及频度如下表:

字符空格ABCDEFGHIJKLMNOPQRSTUVWXYZ

频度18664132232103211547571532205763151485180238181161

通过此次课程设计主要达到以下目的:

1.了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;

2.初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;

3.提高综合运用所学的理论知识和方法独立分析和解决问题的能力;

4.训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风。

本程序采用VisualC++编程实现。

2概要设计

2.1总体功能结构

本程序的主要功能是实现对用户输入的字符编码,然后再把编码结果翻译

成原字符。

但在进行这些操作之前必须做一项工作,就是创建Huffman树。

哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。

所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。

树的带权路径长度记为WPL=(W1*L1+W2*L2+W3*L3+...+Wn*Ln),N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n)。

可以证明哈夫曼树的WPL是最小的。

哈夫曼在上世纪五十年代初就提出这种编码时,根据字符出现的概率来构造平均长度最短的编码。

它是一种变长的编码。

在编码中,若各码字长度严格按照码字所对应符号出现概率的大小的逆序排列,则编码的平均长度是最小的。

总体功能流程如下图:

2.2数据结构设计

2.2.1Huffman结点结构

Huffman结点结构是本程序的基本结构,所有操作都在此上进行。

其中包括存储字符的元素data,字符的权值weight,以及左右孩子指针和父指针。

typedefstruct

{

chardata;//结点值

intweight;//权值

intparent;//父结点指针

intleft;//左孩子结点指针

intright;//右孩子结点指针

}huffnode;

2.2.2编码结构

编码结构用于存储每个字符的编码,包括用于存储编码的数组和用于记录编码个数的元素。

整个结构相当于一个栈结构,采用栈形式存储编码。

 

typedefstruct

{

intcd[M];//编码串

inttop;//串的大小

}huffcode;

2.3方法及原理

2.3.1 创建Huffman树

本文创建Huffman树是在顺序链表的基础上进行的,建树原理如下:

1、根据给定的n个权值{w1,w2,w3,……,wn},构造具有n棵二叉树的森林F={T1,T2,T3,……,Tn},其中每棵二叉树Ti只有一个带权值wi的根结点,其左右子树均为空。

2、重复以下步骤,直到F中仅剩下一棵树为止:

(1)在F中选取两棵根结点的权值最小的二叉树,作为左右子树构造一棵新的二叉树。

使新的二叉树的根结点的权值为其左右子树上根结点的权值之和。

(2)在F中删去这两棵二叉树,把新的二叉树加入F。

最后得到的就是Huffman树。

2.3.2编码

编码操作需在建立好Huffman树的基础上进行。

二叉树的叶子结点标记字符,由根结点沿着二叉树路径下行,左分支标记为0,右分支标记为1,则每条从根结点到叶子结点的路径唯一表示了该叶结点的二进制编码。

编码的时候,我们采用从叶子结点向上回溯的方法编码,如果当前结点是其父结点的左孩子,则编码为0,如果是右孩子,则编码为1,如此回溯,直到父结点为空时,该字符的编码就结束了,对应编码结构中的编码数组就是该字符的编码。

如此操作,直到所有叶子结点都扫描一遍为止,即编码结束。

2.3.3译码

译码操作也是在前面创建的Huffman树的基础上进行。

对译码字符串从头往后扫描,如果是1,则当前指针指向右孩子,如果是0,则指向左孩子。

如此下去,直到指针为空时,当前结点的data值就是译码。

然后再从头开始扫描,进行上面操作,当编码字符串扫描结束时,译码结束。

3详细设计和实现

3.1创建Huffman树

3.1.1功能描述

Huffman树是整个程序的核心部分,是编码译码操作的前提。

哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。

根据字符出现的概率来构造平均长度最短的编码。

它是一种变长的编码。

在编码中,若各码字长度严格按照码字所对应符号出现概率的大小的逆序排列,则编码的平均长度是最小的。

3.1.2算法原理

首先根据用户输入创建n棵子树的森林,然后对所有子树扫描,找出权值最小的两个子树,把它们合并成一棵新的子树,同时把它们的权值之和作为新树的权值。

把这两棵子树删掉,再把新树加如到森林中,然后再扫描出权值最小的两棵子树,接着进行同样的操作,直到只剩下一棵树即为Huffman树。

 

3.3.3算法流程

3.3.4具体程序

voidselect(huffnodehn[],intk,int&s1,int&s2)

//选取父结点为空且权值最小的两个结点

{

intminw=200;//暂存最小权值

inti;

for(i=1;i<=k;i++)

if(hn[i].weight

{

minw=hn[i].weight;

s1=i;//s1存储权值最小结点编号

}

minw=200;

for(i=1;i<=k;i++)

if(hn[i].weight

=s1)

{

minw=hn[i].weight;

s2=i;//s2存储权值第二小的结点编号

}

}

voidcreatht(huffnodehn[],intn)//创建huffman树

{

inti;

ints1,s2;

for(i=n;i<2*n-1;i++)

{

select(hn,i,s1,s2);

hn[s1].parent=i+1;

hn[s2].parent=i+1;

hn[i+1].left=s1;

hn[i+1].right=s2;

hn[i+1].weight=hn[s1].weight+hn[s2].weight;

}

}

3.2编码

3.2.1功能描述

编码的功能就是把字符转换成二进制数来存储

3.2.2算法原理

编码的时候,我们采用从叶子结点向上回溯的方法编码,如果当前结点是其父结点的左孩子,则编码为0,如果是右孩子,则编码为1,如此回溯,直到父结点为空时,该字符的编码就结束了,对应编码结构中的编码数组就是该字符的编码。

如此操作,直到所有叶子结点都扫描一遍为止,即编码结束。

3.2.3算法流程

3.2.4具体程序

voidEncode(huffnodehn[],intn,huffcodehc[])//编码函数

{

inti,j,p;

for(i=1;i<=n;i++)//对每个字符编码

{

intt=-1;

j=i;

while(hn[j].parent!

=0)//当前结点的父结点非空

{

p=j;

j=hn[j].parent;

if(hn[j].left==p)

//如果当前结点是父结点的左孩子,则编码为0

hc[i].cd[++t]=0;

if(hn[j].right==p)

//如果当前结点是父结点的右孩子,则编码为1

hc[i].cd[++t]=1;

}

hc[i].top=t;//存储编码串大小

}

}

3.3译码

3.3.1功能描述

译码功能主要是把二进制编码翻译成字符形式。

3.3.2算法原理

从头往后扫描待译字符串,如果是1,则当前指针指向右孩子,如果是0,则指向左孩子。

如此下去,直到指针为空时,当前结点的data值就是译码。

然后再从头开始扫描,进行上面操作,当编码字符串扫描结束时,译码结束。

3.3.3算法流程

3.3.4具体程序

voidDecode(huffnodehn[],intn,intstr[])//译码函数

{

intk=0;

intp;

while(str[k]==0||str[k]==1)

//待译码串值不为1或0退出循环,即译码结束

{

p=2*n-1;

while(hn[p].left!

=0)//当前结点存在孩子结点

{

if(str[k]==1)//如果待译码值为1,则指针指向右孩子

p=hn[p].right;

if(str[k]==0)//如果待译码值为0,则指针指向左孩子

p=hn[p].left;

k++;

}

cout<

}

cout<

}

4调试与操作说明

由上文的分析可见,在运行程序时,需先输入需要编码的字符串,然后根据输入的字符的权重创建Huffman树,接着再进行编码操作,最后再把所得的编码进行译码,各步操作之间存在先后关系,因此在运行程序时必须注意所选择的操作的先后顺序。

具体程序运行过程举例如下:

总结

我们这次做的是哈弗曼编码译码器。

在当今信息爆炸时代,如何采用有效的数据压缩技术节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视,哈夫曼正是一种应用广泛且非常有效的数据压缩技术。

哈夫曼编码的应用很广泛,利用哈夫曼树求得用于通信的二进制编码称为哈夫曼编码。

树中从根到每一个叶子都有一条路径,对路径上的各分支约定:

指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各叶子对应的字符的编码,这就是哈夫曼编码。

由于我的基础不太好,我主要做的只是哈弗曼树的创建和编码的一部分,首先进行初始化:

键盘输入字符集大小n、n个字符和n个权值,建立哈夫曼树本文创建Huffman树是在顺序链表的基础上进行的,编码操作则在建立好Huffman树的基础上进行。

虽然程序最后成功运行了,但我知道这次程序还是以我的搭档为主,而且我同样认识到要独自完成一项“大”工程是多么困难。

通过此次课程设计我发现,在平时的学习中,我们不能单单地只学习理论知识,而应当把理论知识与实践结合起来。

不然如果只有理论知识,而不能把理论运用到实际中,那也没多大用。

总的来说,在此次的课程设计中我学到了许多平时在课本中不能学到的东西,也使我分析处理问题的能力有了提高,可谓受益无穷。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1