哈夫曼编码和译码系统

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

通达学院

算法与数据结构程序设计

题目:哈夫曼编码和译码系统

专业

学生姓名

班级学号

指导教师

指导单位

日期

一、题目要求:题目:哈夫曼编码和译码系统

基本要求: (1) 能输入字符集和各字符频度建立哈夫曼树;

(2) 产生各字符的哈夫曼编码,并进行解码。

提高要求: (1) 能设计出简捷易操作的窗口界面;

(2) 编码和译码存储在文件中。

二、需求分析:

2.1基本思想

根据,哈夫曼的定义,一棵二叉树要使其带权路径长度最小,必须使权值越大的叶子结点越靠近根结点,而权值越小的叶子结点越远离根结点.依据这个特点便提出了哈夫曼算法,其基本思想是:

(1)初始化:由给定的n个权值{w

1, w

2

,…, w

n

}构造n棵只有一个根结点的

二叉树,从而得到一个二叉树集合F={ T

1,T

2

,…,T

n

};

(2)选取与合并:在F中选取根结点的权值最小的两棵二叉树分别作为左、

右子树构造一颗新的二叉树,这棵新二叉树的根结点的权值为其左、右子树根结点的权值之和;

(3)删除与加入:在F中删除作为左、右子树的两棵二叉树,并将新建立的二

叉树加入到F中;

(4)重复(2)、(3)两步,当集合F中只剩下一棵二叉树时,这棵二叉树便是哈

夫曼树.

2.2存储结构

在由哈夫曼算法构造的哈夫曼树中,非叶子结点的度均为2,根据二叉树的性质可知,具有n个叶子结点的哈夫曼树共有2n-1个结点,其中有n-1个非叶子结点,它们是在n-1次的合并过程中生成的.为了便于选取根结点权值最小的二叉树以及合并操作,设置一个数组HuffmanNode[2n-1]保存哈夫曼树中各结点的信息,数组元素的结点结构如图所示.

图哈夫曼树的结点结构

其中:

weight:权值域,保存该结点的权值;

Lchild:指针域,保存该结点的左孩子结点在数组中的下标;

Rchild:指针域,保存该结点的右孩子结点在数组中的下标;

parent:指针域,保存该结点的双亲结点在数组中的下标.

三、概要设计:

1.我首先创建了两个结构体HTNode和Node,分别来记录哈弗曼树各节点的信息以及叶子节点的信息。

建立六个成员函数,如下图所示:

各功能函数实现如下功能:

1、void CreateWeight(){......}

作用:产生叶子结点的字符和权值。

2、void CreateHuffmanTree(){......}

作用:创建HuffmanTree。

3、void CrtHuffmanNodeCode(){......}

作用:生成叶子结点的编码

4、void CrtHuffmanCode(){......}

作用:生成所有字符的编码

5、void TrsHuffmanTree( ){......} 作用:解码

6、主函数main()

四、详细设计

○1void CreateWeight(char ch[],int *s,WeightNode CW,int *p)

其中形参分别表示:

char ch[]//存放用户输入的字符串

int *s//字符串ch[]的长度

WeightNode CW//存放叶子节点的信息

int *p//叶子节点的个数

核心功能:

函数通过定义三个变量i,j,k,来控制三个循环,主要是为了遍历字符串,找出叶子节点的字符与权值信息。

○2void CreateHuffmanTree(Huffman ht,WeightNode CW,int n)

形参表示:

Huffman ht//Huffman的一个对象ht

WeightNode CW//权值大小

int n//叶子节点的个数

功能描述:

函数先通过两个for循环对哈夫曼树进行初始化,然后在通过一个循环每次找出权值最小的两个节点,进行权值相加。

○3void CrtHuffmanNodeCode(Huffman ht,char ch[],HuffmanCode h,WeightNode weight,int m,int n)

形参表示:

Huffman ht//Huffman的一个对象

char ch[]//存放用户输入的字符串

HuffmanCode h//存放叶子节点的编码

WeightNode weight//叶子节点的信息(字符与权值)

int m//字符串ch[]的长度

int n//叶子节点的个数

函数功能:

这个函数从每个叶子节点出发,通过比较父类的左孩子的数组下标是否与对应的左孩子下标相同,相同则置0,不同则置1.(从后往前置数)

核心代码:

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

{ start=n-1; //cd串每次从末尾开始

c=i;

p=ht[i].parent;//p在n+1至2n-1 while(p) //沿父亲方向遍历,直到为0 {

start--;//依次向前置值

if(ht[p].LChild==c)//与左孩子结点在数组中的下标相同,置0 cd[start]='0';

else //与右孩子结点在数组中的下标相同,置1 cd[start]='1';

c=p;

p=ht[p].parent;

}

○4void CrtHuffmanCode(char ch[],HuffmanCode h,HuffmanCode hc,WeightNode

weight,int n,int m)

功能描述:

通过循环遍历整个字符串,再通过判断每一个字符串与相应的叶子节点的字符相

同,相同的话,则将该叶子节点的编码拷贝到hc[]数组中。完成所有字符的编码。

核心代码:

for(i=0;i

{

for(k=1;k<=n;k++) /*从weight[k].c中查找与ch[i]相等的下标

K*/

if(ch[i]==weight[k].c)

break;

hc[i]=(char *)malloc((weight[k].num)*sizeof(char));

strcpy(hc[i],h[k]); //拷贝二进制编码

}

}

○5void TrsHuffmanTree(Huffman ht,WeightNode w,HuffmanCode hc,int n,int m)

功能描述:TrsHuffmanTree(ht,weight,hc,n,m);为该函数的调用

其中:ht,weight,hc,n,m,分别表示哈夫曼对象,叶子节点对象,存放所有字符编

码的数组hc,叶子节点的个数n,一起字符串的长度m。

核心代码:

while(i

{

相关文档
最新文档