目录
哈夫曼树的基本概念
哈夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,在实际中有广泛的用途。哈夫曼树的定义,涉及路径、路径长度、权等概念。
(1)路径:从树中一个节点到另一个节点之间的分支构成这两个节点之间的路径。
(2)路径长度:路径上的分支数目称作路径长度。
(3)树的路径长度:从树根到每一叶子节点的路径长度之和。
(4)权:赋予某个实体的一个量,是对实体的某个或某些属性的数值化描述。
(5)节点的带权路径长度:从该节点到树根之间的路径长度与节点上权值的乘积。
(6)树的带权路径长度:树中所有叶子节点的带权路径长度之和,通常记作WPL。
(7)哈夫曼树:假设有m个权值{wl,w2,…,wm},可以构造一棵含n个叶子节点的二叉,每个叶子节点的权值为wi,则其中带权路径长度WPL最小的二叉树称作最优二叉树或哈夫曼树。
哈夫曼树的构造过程
(1)根据给定的n个权值{wi,W2,…,wn},构造n棵只有根节点的二叉树,这n棵二叉树构成森林F。
(2)在森林F中选取两棵根节点的权值最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根节点的权值为其左、右子树上根节点的权值之和。
(3)在森林F中删除这两棵树,同时将新得到的二叉树加入F中。
(4)重复(2)和(3),直到F只含一棵树为止。这棵树便是哈夫曼树。
在构造哈夫曼树时,首先选择权值小的,这样保证权值大的离根较近,这样一来,在计算树的带权路径长度时,自然会得到最小带权路径长度,这种生成算法是一种典型的贪心法。
哈夫曼算法的实现
1、哈夫曼树是一种二叉树,当然可以采用前面介绍过的通用存储方法,而由于哈夫曼树中没有度为1的节点,则一棵有 n个叶子节点的哈夫曼树共有2n-1个节点,可以存储在一个大小为2n-1的一维数组中。
2、树中每个节点还要包含其双亲信息和孩于节点的信息
存储结构
#include<bits/stdc++.h>
using namespace std;
typedef struct{
int weight;//节点权值
int parent,l,r;//双亲,左孩子,右孩子
}HTnode,*Huffman;
算法实现
void Creat(Huffman &H,int n)
{
if(n<=1) return;
int m=2*n-1;
H=new HTnode[m+1];
for(int i=1;i<=m;i++)//初始化
{
H[i].parent =0;
H[i].l =0;
H[i].r =0;
}
for(int i=n+1;i<=m;i++)
{
cin>>H[i].weight;//输入叶子节点的权值
}
/*--------初始化结束---------*/
for(int i=n+1;i<=m;i++)//通过n-1次的选择,删除,合并创建哈夫曼树
{
//选择最小的
select(H,i-1,s1,s2);
H[s1].parent =i;
H[s2].parent =i;
H[i].l=s1;
H[i].r=s2;
H[i].weight =H[s1].weight+H[s2].weight ;
}
}