哈夫曼树
定义: 在一个二叉树中,若带权长度达到最小,则称这样的二叉树为最优二叉树,也称为哈夫曼树。
哈夫曼树的构造:
假设有n个权值,则构造出的哈夫曼树有n个叶子结点。n个权值分别设为 w1,w2,…,wn , 则哈夫曼树的构造规则为:
- 将 w1,w2,…,wn 看成有n棵树的森林。
- 在森林中选出两个根节点的权值最小的树合并,作为一棵新的左、右子树,且新的树的根节点权值为其左右子树根节点权值之和。
- 从森林中删除选取的两棵树,并将新树加入森林。
- 重复步骤2,3直到森林只剩一棵树为止,该树即为所求得的哈夫曼树。
下面给出哈夫曼树的构造过程,假定给定的叶子节点的权分别为1,5,7,3,则构造哈夫曼树的过程如图
1.初始化森林
2.一次合并后的森林
3.二次合并后的森林
4.三次合并后的森林
C++实现代码
定义二叉树结点类
const int MAX=1000;//权重一般不会超过这个数,勉强把它当做无穷大
class btreenode
{
public:
int weight;//权重
btreenode *left,*right;//左右结点
};
定义二叉树类
class btree
{
public:
btreenode *root;
int capacity;
int *a;
void input()
{
cout<<"请输入要建立的树的结点个数";
cin>>capacity;
a=new int[capacity];
for(int i=0;i<capacity;i++)
{
cin>>a[i];
}
}
void build()
{
root=NULL;
int i;
int min=a[0];
int p;//存放找到的最小值位置
while(min<1000)
{
for(i=0,min=a[0],p=0;i<capacity;i++)
{
if(min>=a[i])
{
min=a[i];
p=i;
}
}//找出最小值
if(min<1000)
{
if(root==NULL)//如果哈夫曼树还没有结点,就产生第一个根节点
{
root=new btreenode;
root->weight=a[p];
root->left=NULL;
root->right=NULL;
a[p]=1000;
}
else//如果已经有结点就在把最小值放在现在根节点的兄弟位置
{
btreenode *t;
btreenode *q;
t=new btreenode;
q=new btreenode;
t->weight=a[p];
t->left=NULL;
t->right=NULL;//最小值的节点
a[p]=1000;
q->weight=root->weight+t->weight;//新的根节点,权重为下面两个权重之和
if(root->weight>t->weight)
{
q->left=t;
q->right=root;
root=q;
}
else
{
q->left=root;
q->right=t;
root=q;
}
}
}
}
}
};
代码如果有什么不足,请大佬指点,本人虚心学习