//哈夫曼樹算法
#include<iostream>
using namespace std;
const int n=5;
const int m=2*n-1;
const int float_max=20;
typedef int datatype;
typedef struct
{
float weight; //定義權重
int parent; //定義雙親在向量中的下標
int lchild,rchild; //定義左右子樹
} nodetype; //結點類型
typedef nodetype hftree[m]; //哈夫曼樹類型,數組從0號單元開始使用
hftree T; //哈夫曼樹向量
//哈夫曼樹的構造
void huffman(hftree T)
{
int i,j,p1,p2;
float small1,small2;
for(i=0;i<n;i++) //初始化
{
T[i].parent=-1; //無雙親,即為根結點,尚未合並過
T[i].lchild=T[i].rchild=-1;//左右孩子指針置為-1
}
for(i=0;i<n;i++)
{
cin>>T[i].weight; //輸入n個葉子的權
}
for(i=n;i<m;i++) //進行n-1次合並,產生n-1個新結點
{
p1=p2=-1;
small1=small2=float_max; //float_max為float類型的最大值
for(j=0;j<=i-1;j++)
{
if(T[j].parent!=-1) continue;//不考慮已合並過的點
if(T[j].weight<small1) //修改最小權和次小權及位置
{
small2=small1;
small1=T[j].weight;
p2=p1;
p1=j;
}
else if(T[j].weight<small2) //修改次小權及位置
{
small2=T[j].weight;
p2=j;
}
}
T[p1].parent=T[p2].parent=i; //新根
T[i].parent=-1;
T[i].lchild=p1;
T[i].rchild=p2;
T[i].weight=small1+small2; //新結點的權值為最小權與次小權之和
}
}
int main()
{
hftree T;
cout<<" 歡迎測試!!!! "<<endl;
cout<<"----------測試開始-----------"<<endl;
cout<<"首先調用哈夫曼樹構造的函數:huffman"<<endl;
cout<<"按下標順序輸入葉子的權重:"<<endl;
cout<<" 0 1 2 3 4 5 6 7 8 "<<endl;
huffman(T);
cout<<"輸出合並后的哈夫曼樹的所有結點:"<<endl;
cout<<" 0 1 2 3 4 5 6 7 8 "<<endl;
for(int i=0;i<m;i++)
{
cout<<T[i].weight<<" ";
}
system("pause");
return 0;
}