哈夫曼树编码与译码(完整C/C++实现代码)

哈夫曼编码的设计与应用

问题需求分析

用哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。
霍夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的路径长度是从树根到每一结点的路径长度之和,记为WPL=(W1L1+W2L2+W3L3+…+WnLn),N个权值Wi(i=1,2,…n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,…n)。

数据结构的定义

哈夫曼树结构体包含如下内容:节点权重,当前节点的父节点,左右子树,节点信息。
哈夫曼编码结构体包含如下内容:存编码的数组,编码数组的开始标志。

功能详细设计

构建哈夫曼树:使用一维数组,每个节点存储权重,父节点,左子树,右子树,以及数值的信息。遍历整个数组,根据每个节点的权重去找到最小以及第二小的节点,然后对各自的父节点,左右子树赋值,建立两个节点的联系将他们的联系填入该结构体数组中。
哈夫曼树如下图:
a权重45; b权重15; c权重12; d权重16; e权重9; f权重5
哈夫曼树编码与译码(完整C/C++实现代码)_第1张图片
哈夫曼树结构体数组如下图(使用a, b, 58举例):
哈夫曼树编码与译码(完整C/C++实现代码)_第2张图片
根据哈夫曼树建立哈夫曼编码:从树的根节点开始,根据每个叶子节点与父节点之间的联系,使用哈夫曼编码结构体中的编码数组储存树种每个叶子节点的编码, 往左边遍历是0, 往右边遍历是1, 举例: a, 由建立好的哈夫曼树可得, 当遍历查找到a的时候, a到root的路径是: 100->86->58->a, 所以可得编码就是000;

根据哈夫曼编码将指定的编码转化为字符串:读取到哈夫曼编码后,当编码为0表示节点是左子树,当编码为1的时候表示右子树,根据已经建立好的哈夫曼树,利用顺序遍历的方式,根据左0右1,寻找哈夫曼树中的叶子节点,当某一节点在哈夫曼树中左右子树都为空的时候,表示该节点即使叶子节点,然后输出对应叶子节点在哈夫曼编码数组中的位置, 其原理与编码的方式恰恰相符, 而是根据01数字查找对应的叶子节点.

函数调用图:

哈夫曼树编码与译码(完整C/C++实现代码)_第3张图片

编写代码体会

遇到的问题是数组下标没有弄好,导致建立哈夫曼树时出现各种错误, 进行编码过程没有将lchild与rchild的”变化写在一起”导致出现错误,其实最大的问题是:没有将代码的逻辑思路考虑清楚,还有边界条件值,最蠢的是没有打一下草稿,写一下伪代码,把程序的思想理解,导致编程的过程中出现各种问题,以后写代码之前还是把逻辑理清楚再动手写代码,最后再将代码写到电脑上测试。

完整代码

#include
#include
#include 
using namespace std;
struct Htnode{
	int weight,parent,lchild,rchild;
	char c; 
};
struct Htcode{
	int bit[25],start;
};
int type(int a[]){
	string s;
	int sum = 0; 
	cout<<"输入需要编码的字符串"<>s;
	for(int i = 0; i < s.size(); i++){
		a[s[i]-'a']++;
	}
	cout<<"出现的字母种类以及频率:"<=0;j--){
			cout<

上面有错, 还请指出, 如果认为我写的还不错, 还请点个赞, 多多支持一下, O(∩_∩)O~~

你可能感兴趣的:(数据结构,C++)