哈夫曼树
(一)定义
带权路径长度WPL:
哈夫曼树(最优二叉树):
WPL最小的二叉树
(二)构造
将权值从小到大排序,后将权值最小的两个并在一起成新的二叉树
A5,E10,B15,D30,C40
(三)哈夫曼树特点
1.没有度为1的结点
2.n个叶子节点的哈夫曼树共有2n-1个结点
树的特点:度为2结点和叶结点的关系n2=n0-1所以:当叶结点为n时,度为二的结点数为n-1因为哈夫曼没有度为一的结点,所以一共在树中有2n-1个结点
3.哈夫曼树任意非叶结点的左右子树交换后还是哈夫曼树
4.对同一组权值{w1,w2,...,wn},是会存在不同结构的哈夫曼树
哈夫曼编码
固定一段字符串,如何对字符串进行编码,可以使得该字符串的编码存储空间最少
例如一串文字BADCADFEED,我们要在网络中传递,显然是要传递二进制(0/1)来表示。
法一:直接传递字符的ASCII码,每个字符占八位,一共传递80位
法二:我们发现数据只是从A-F,一共6个字符,我们完全可以使用3位二进制来表示这些数据(网络对方需要知道我们的编码才能解码)
001000011010000011101100100011(30)
变为传递30位数据,对法一进行了极大的优化。
法三:我们发现一段文字中各个数字出现的频率是不一样的,各个字母频率相加100%,可以使用哈夫曼编码,对数据再次进行压缩
假设各个字母频率为
A27,B 8,C 15,D 15,E 30,F 5
1.先构造哈夫曼树
2.获取前缀码
(1)左右分支分别用0,1表示(避免了二义性)
(2)字符只在叶子节点
哈夫曼压缩后的数据二进制串:1001010010101001000111100(25)
哈夫曼编码实现
头文件
#pragma once#ifndef _HUFFMAN_H#define _HUFFMAN_H
//下面两个结构体对于霍夫曼树
typedef struct_htNode
{charsymbol;struct _htNode* left, *right;
}htNode;
typedefstruct_htTree
{
htNode*root;
}htTree;//下面两个结构体对应霍夫曼编码表
typedef struct_hlNode
{charsymbol;char* code; //类似'0001\0'
struct _hlNode*next;
}hlNode;
typedefstruct_hlTable
{
hlNode*first;
hlNode*last;
}hlTable;//根据字符串创建霍夫曼树