构造哈夫曼树算法C/C++
一、哈夫曼树的基本概念
最优二叉树也称哈夫曼树,是指对于一组带有确定权值的叶节点,构造的具有最小带权路径长度的二叉树。
二、哈夫曼树的结构
假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:
(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);
(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;
(3)从森林中删除选取的两棵树,并将新树加入森林;
(4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树
三、构造哈夫曼树算法
/*
*构造哈夫曼树算法
*/
#include<stdio.h>
#include<malloc.h>
#define MAXVALUE 1000 //定义最大权值
#define MAXLEAF 30 //定义最大叶子树
#define MAXNODE 2 * MAXLEAF - 1
/*
*定义哈夫曼树的存储结构
*/
typedef struct
{
int weight ; //权值
int parent ; //父节点的位置
int lchild ;
int rchild ;
} HNodeType ;
/*
*构造哈夫曼树算法
*/
void HaffmanTree(HNodeType HuffNode [])
{
int i , j , m1 , m2 , x1 , x2 , n ;
scanf("%d" , &n) ; //输入叶子节点个数
/*
*哈夫曼树的初始化
*/
for(i = 0 ;i < 2 * n - 1 ; i++)
{
HuffNode[i].weight = 0 ;
HuffNode[i].parent = -1 ;
HuffNode[i].lchild = -1 ;
HuffNode[i].rchild = -1 ;
}
for(i = 0 ;i < n ; i++)
{
scanf("%d" , &HuffNode[i].weight) ; //输入各个叶子节点的权值
}
/*
*构造哈夫曼树
*/
for(i = 0 ; i < n - 1 ; i++)
{
m1 = m2 = MAXVALUE ;
x1 = x2 = 0 ;
/*
*选取两棵权值最小的子树
*/
for(j = 0 ; j < n + i ; j++)
{
if(HuffNode[j].weight < m1 && HuffNode[j].parent == -1)
{
m2 = m1 ;
x2 = x1 ;
m1 = HuffNode[j].weight ;
x1 = j ;
}
else if(HuffNode[j].weight < m2 && HuffNode[j].parent == -1)
{
m2 = HuffNode[j].weight ;
x2 = j ;
}
}
/*
*将找出的两棵子树合并为一棵子树
*/
HuffNode[x1].parent = n + i ;
HuffNode[x2].parent = n + i ;
HuffNode[n+i].weight = HuffNode[x1].weight + HuffNode[x2].weight ;
HuffNode[n+i].lchild = x1 ;
HuffNode[n+i].rchild = x2 ;
}
for(i = 0 ; i < 2 * n - 1 ; i++)
{
printf("%d %d %d %d \n" , HuffNode[i].weight , HuffNode[i].parent , HuffNode[i].lchild , HuffNode[i].rchild) ;
}
}
/*
*进行哈夫曼树的测试
*/
void main()
{
HNodeType HuffNode[MAXNODE] ;
HaffmanTree(HuffNode) ;
}