哈夫曼编码和译码系统
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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 {