《数据结构》课程设计(赫夫曼编码/译码器)

本文介绍了一个使用C++实现的赫夫曼编码/译码器课程设计。系统包括初始化、编码和译码三个功能,旨在提高信道利用率。通过构建哈夫曼树,实现对字符的不等长编码,以达到节省传输成本的目的。文章详细讨论了哈夫曼树的建立、编码存储结构、译码过程以及程序设计的详细步骤,还分析了在实现过程中遇到的问题和解决方案。
摘要由CSDN通过智能技术生成

一、题目

一、赫夫曼编码/译码器

1. 问题描述
利用赫夫曼编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。这要求在发送端通过一个编码系统对待传输数据预先编码,在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站编写一个赫夫曼码的编/译码系统。

2.基本要求
一个完整的系统应具有以下功能:
(1) I:初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立赫夫曼树,并将它存于文件hfmTree中。
(2) E:编码(Encoding)。利用已建好的赫夫曼树(如不在内存,则从文件hfmTree中读入),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。
(3) D:译码(Decoding)。利用已建好的赫夫曼树将文件CodeFile中的代码进行译码,结果存入文件Textfile中。

二、需求分析
实验目的:掌握哈夫曼数及其应用
实验内容:利用哈夫曼算法,构造最优的二叉数,然后对构造好的二叉树的叶子结点进行前缀编码。
实验步骤:(1)审清题意,分析并理出解决问题的基本思路。(2)根据基本思路,设计好程序的算法。(3)根据算法编写源程序(4)在计算机上编译程序,检验程序的可运行性。

三、概要设计
哈夫曼编译码器的主要功能是先建立哈夫曼树,然后利用建好的哈夫曼树生成哈夫曼编码后进行译码。
在数据通信中,通常需要将传送文字转换成由二进制字符0,1组成的二进制串,称之为编码。构建一个哈夫曼树,设定哈夫曼树中的左分支为0,右分支代表1,则从根结点到每个叶子节点所经过的路径组成的0和1的序列便为该节点对应字符的编码,称之为哈夫曼编码。
最简单的二进制编码方式是等长编码。若采用不等长编码,让出现频率高的字符具有较短的编码,让出现频率低的字符具有较长的编码,这样可以有效缩短传送文字的总长度。哈夫曼树则是用于构造使编码总长最短,最节省空间成本的编码方案。

设计包含几个方面:1、哈夫曼树的建立
哈夫曼树的建立由哈夫曼算法的定义可知,初始森林中共有n课只含有根节点的二叉树,算法的第二步是:当前森林中两颗根节点权值最小的二叉树,合并为一个新的二叉树,每合并一次,森林中就减少一棵树,产生一个新节点,要进行n-1次的合并,共产生n-1个新节点,他们都是具有两个孩子的分支节点。由此可知,最终得到的哈夫曼树中一共有2n-1个节点,其中n个节点是由初始森林的n个孤立节点,哈夫曼树中没有度数为1的分支节点,我们可以利用一个大小为2n-1的一维数组来存储哈夫曼树中的节点。
2、哈夫曼编码
首先定义哈夫曼编码类型,根据实际需要定义类型如下:
Typedef struct//结点的结构,在教科书147页
{ unsigned int weight;
Unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;//动态分配数组存储哈夫曼树
Typedef char * *HuffmanCode;//动态分配数组存储哈夫曼树

3、代码文件的译码
译码的思路是:读取文件中的编码,并与原先生成的哈夫曼编码表进行比较,遇到相等时,取出相应字符存入一个新字符串中。

四、程序说明

主页面进行操作,操作1:
输入字符数量,字符以及其权值,程序运行将编码存入文件中。
操作2:将文件中的字符读取,并编码为二进制编码存入另一个文件。
操作3:从文件中读存储二进制编码,并译码为字符串存入新文件中。

五、详细设计
(1)哈夫曼数和哈夫曼编码的存储结构:

Typedef struct//结点的结构,在教科书147页
{
    unsigned int weight;
  Unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;//动态分配数组存储哈夫曼树
Typedef char * *HuffmanCode;//动态分配数组存储哈夫曼树2)哈夫曼树的算法
Void HuffmanCoding(HuffmanTree &HT,HuffmanTree &HC,int *w,int n){
   
If(n<=1)return;
m=2*n-1;//结点数
HT=(HuffmanTree)malloc((m+1) *sizeof(HTNode));//0号单元未用
For(p=HT,i=1;i<=n;++i,++p,++w)  *p={
   *w,0,0,0};
For( ;i<=m;i++,++p) *p={
   0,0,0,0};
For(i=n+1;i<=m;i++{
    //建哈夫曼树
// 在HT[1...i-1]选择parent为0且weight最小的两个结点,其序号分别为s1和s2.
Select(HT,i-1,s1,s2);
HT[s1].parent=i;HT[s2].parent=i;
HT[i].lchild=s1; HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
//-------从叶子到根逆向求每个字符的哈夫曼编码-----
HC=(HuffmanTree)malloc((n+1)*sizeof(char*));//分配n个字符编码的头指针向量
Cd=(char*)malloc(n*sizeof(char));//分配求编码的工作空间
Cd[n-1] = ‘\0;   //编码结束符
For(i=0;i<=n;i++{
      //逐个字符求哈夫曼编码
   Start=n-1;  //编码结束符的位置
  For(c=i,f=HT[i].parent;f!=
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值