2021年哈夫曼树解压与压缩
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
哈夫曼树的压缩与解压
1.
欧阳光明(2021.03.07)
2.算法简要描述
1.哈夫曼算法
1.哈弗曼算法是根据给定的n个权值{w1,w2,w3.......wn},构
造由n棵二叉树构成的深林F={T1,T2,。。。。Tn},其中每个二叉树Ti分别都是只含有一个权值wi的根结点,其左右子树为空(i=1,,,,,,2)。
2.在深林F中选取其根结点的权值最小的两棵二叉树,分别作
其左右子树构造一颗新的二叉树,并置这棵新的二叉树根结点的权值为其左右子树的根结点之和。
3.从F中删去这两棵二叉树,同时刚新生成的二叉树加入到深
林F中。
4.重复2,3,步骤,直至深林F中只含有一颗二叉树为止。
2.哈夫曼树的实现
函数String EnCode(Char Type ch):表示哈夫曼树已存在,返回字符ch的编码。
函数LinkList
F中就只剩下一棵树了。另外,每次合并都要产生一个新的结点,合并n-1次后共产生了n-1个新结点,并且这n-1个新节点都是具有左右子树的分支结点。则最终得到的哈夫曼树中共有2n-1个结点,并且其中没有度为1的分支结点,最后一次产生的新结点就是哈夫曼树的根结点。
源代码中创建了一个哈夫曼树结点类,其中有数据成员weight,parent,leftChild,rightChild分别代表了权值,双亲,左孩子,右孩子。
在哈夫曼树类中有数据成员*nodes,*LeafChars,*LeafCharCodes,curPos,num,分别用来存储结点信息,叶结点字符信息,叶结点字符编码信息,译码时从根结点到叶结点路径的当前结点,叶结点个数。哈夫曼树类中含有多个函数,有构造函数,析构函数等。由函数HuffmanTree(CharType ch[],WeightType w[],int n)来构造由字符,权值,和字符个数构造哈夫曼树,在根据哈夫曼算法很容易实现哈夫曼类的函数以及构造函数。在在算法中,求叶结点字符的编码时,需要从叶结点出发走一条从高叶结点到根结点的路径,而编码却是从根结点出发到叶结点的路径,由左分支为编码0,右分支为编码1,得到的编码,因此从叶结点出发到根结点的路径得到的编码是实际编码的逆序,并且编码长度不确定,又由于可以再线性链表中构造串,因此将编码的信息储存在一个线性立案标准,每得到一位编码都将其插入在线性链表的最前面。
在求某个字符的编码是由函数EnCode(CharType ch)来求,返回字符
编码。在进行译码时,用一个线性链表存储字符序列,由函数Decode(String strCode)来求,对编码串strCode进行译码,返回编码前的字符序列。函数Compress()用哈夫曼编码压缩文件。函数Decompress()解压缩用哈夫曼编码压缩的文件。
在主函数中有两个选项,一个是选择编码压缩,一个是解压。在函数中使用了文件输入输出流,我们可以选择要压缩的文件名输入,在选出压缩文件保存的地方和文件类型,将压缩所得到的文件存储在另一个文件中,解压也是如此。
3.源代码
#ifndef __HUFFMAN_TREE_NODE_H__
#define __HUFFMAN_TREE_NODE_H__
// 哈夫曼树结点类模板
template
struct HuffmanTreeNode
{
WeightType weight; // 权数据域
unsignedint parent, leftChild, rightChild; // 双亲,左右孩子域HuffmanTreeNode(); // 无参数的构造函数模板
HuffmanTreeNode(WeightType w, int p = 0, int lChild = 0, int rChild = 0);
// 已知权,双亲及左右孩子构造结构
};
// 哈夫曼树结点类模板的实现部分
template
HuffmanTreeNode
{
parent = leftChild = rightChild = 0;
}
template
HuffmanTreeNode
{
weight = w; // 权
parent = p; // 双亲
leftChild = lChild; // 左孩子
rightChild = rChild; // 右孩子
}
#endif
#ifndef __HUFFMAN_TREE_H__
#define __HUFFMAN_TREE_H__
#include"string.h"// 串类
#include"huffman_tree_node.h"// 哈夫曼树结点类模板
// 哈夫曼树类模板
template
class HuffmanTree
{
protected:
HuffmanTreeNode
CharType *LeafChars; // 叶结点字符信息,LeafChars[0]未用
String *LeafCharCodes; // 叶结点字符编码信息,LeafCharCodes[0]未用
int curPos; // 译码时从根结点到叶结点路径的当前结点
int num; // 叶结点个数
// 辅助函数模板:
void Select(int cur, int &r1, int &r2); // nodes[1 ~ cur]中选择双亲为,权值最小的两个结点r1,r2
void CreatHuffmanTree(CharType ch[], WeightType w[], int n);
// 由字符,权值和字符个数构造哈夫曼树
public:
// 哈夫曼树方法声明及重载编译系统默认方法声明:
HuffmanTree(CharType ch[], WeightType w[], int n); // 由字符,