哈夫曼树
路径:从一个结点到另一个结点之间的分支构成这两个结点之间路径
树的路径长度:从Root到每一个结点的路径长度之和
结点数码相同的二叉树中,完全二叉树是路径长度最短的二叉树
(路径长度最短的二叉树不一定是完全二叉树)
权:给结点赋一个具有某种含义的值
结点的带权路径长度:Root到该结点之间的路径长度 * 权值
WPL树的带权路径长度:树种所有Leaf结点的带权路径长度之和
哈夫曼树:最优树:WPL最短的树
具有相同带权结点的哈夫曼树不唯一
构造森林全是根
选用两小造新树
删除两小添新人
重复2、3剩单根
哈夫曼树中只有度为0、2的结点,没有度为1的结点
包含n个叶子结点的哈夫曼树中共有2n-1个结点
顺序存储结构
typedef struct{
int weight;
int parent,lch,rch;
}HTNode,*HuffmanTree;
共有2n-1个结点,不使用0为下标,2n
void CreatHuffmanTree(HuffmanTree HT, int n){
if(n<=1) return;s
m= 2*n - 1;
HT = new HTNode[m+1];
for(i=1; i<=m;++i){
HT[i].lch = 0;
HT[i].rch = 0;
HT[i].parent = 0;
}
for(i = 1; i<=n; ++i) cin>>HT[i].weight;
for(i = n+1; i <= m; i++){
Select(HT, i-1, s1, s2)
HT[s1].parent = i; HT[s1].parent = i;
HT[i].lch = s1; HT[i].rch = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight
}
}
哈夫曼编码(看书)
任意一个编码都不是另一个字符的编码的前缀 ---前缀编码
为什么哈夫曼编码是前缀编码呢?
因为没有一个树叶是另一片的祖先
为什么Huffman编码能够保证字符编码总长最短
因为Huffman树的带权路径长度最短
左分支 0 右分支 1
一看就懂,真的
BUT,这种方法我们看好看,计算机具体算法实现较为困难
计算机从叶子往上找较为方便
假设要得到G
从七号结点开始,取7号的parent值8,八号结点是其双亲,
查8号的左右孩子,是左孩子就0、右孩子1,
一直这样找,找到parent = 0
最后逆序取
有几个结点就要做多少次
我是没太懂
void CreatHuffmanCode(Huffman HT, HuffmanCode & HC, int n){
从叶子到root逆向求每个字符的哈夫曼编码,存储在编码表HC中
HC = new char*[n+1];
cd = new char[n];
cd[n-1] = '\0';
for(i = 1; i <= n; ++i){
start = n-1; c = i; f = HT[i].parent;
while(f != 0){
--start;
if(HT[f].lchild = c) cd[start] = '0';
else cd[start] = '1';
c = f;f = HT[f].parent;
}
HC[i] = new char[n-start];
strcpy(HC[i], &cd[start]);
}
delete cd;
}