哈夫曼树
#include "iostream"
#include "string.h"
using namespace std;
//定义哈夫曼树存储结构
typedef struct{
int weight;//权重
int parent,lc,rc;//指向双亲、左孩子、右孩子指针
}HTNode,*HuffmanTree;
//定义哈夫曼编码存储结构
typedef char** HuffmanCode;
//选择两个最小权重的结点
void SelectMin(HuffmanTree ht,int n,int &s1,int &s2){
int i;
//查找第一个无双亲的结点
for(i=1;i<=n;i++)
if(ht[i].parent==0){
s1=i;
break;
}
//查找权重第一小的结点
for(;i<=n;i++){
if(ht[i].parent==0 && ht[i].weight<ht[s1].weight)
s1=i;
}
for(i=1;i<=n;i++)
if(ht[i].parent==0 && i!=s1){
s2=i;
break;
}
//查找权重第二小的结点
for(i=1;i<=n;i++)
if(ht[i].parent==0 && i!=s1)
if(ht[i].weight<ht[s2].weight)
s2=i;
}
//建立哈夫曼树
void CreateHuffmanTree(HuffmanTree &ht,int *w,int n){
int i,m,s1,s2;
if(n<=1)
return;
m=2*n-1;//m是总的哈夫曼树结点数
//动态申请m+1个HTNode存储单元,0号单元不用
ht=new HTNode[m+1];
//初始化n个叶子结点
for(i=1;i<=n;i++){
ht[i].weight=w[i-1];
ht[i].parent=ht[i].lc=ht[i].rc=0;
}
//初始化n-1个非叶结点
for(;i<=m;i++){
ht[i].parent=ht[i].lc=ht[i].rc=0;
}
for(i=n+1;i<=m;i++){
//选择两个权值最小的结点,分别用s1,s2标识
SelectMin(ht,i-1,s1,s2);
//生成树根结点的权重等于其左右孩子权重之和
ht[i].weight=ht[s1].weight+ht[s2].weight;
//左右孩子的双亲等于新生成的结点
ht[s1].parent=ht[s2].parent=i;
ht[i].lc=s1;//生成结点的左孩子等于s1
ht[i].rc=s2;//生成结点的左孩子等于s2
}
}
//对立哈夫曼编码
void CreateHuffmanCode(HuffmanCode &hc,HuffmanTree ht,int n){
int i,c,f,start;
hc=new char*[n+1];
char *cd=new char[n];
cd[n-1]='\0';
for(i=1;i<=n;i++){
start=n-1;
c=i;
f=ht[c].parent;
while(f!=0){
if(c==ht[f].lc)
cd[--start]='0';
else
cd[--start]='1';
c=f;
f=ht[c].parent;
}
hc[i]=new char[n-start];
strcpy(hc[i],&cd[start]);
}
}
//打印哈夫曼编码
void PrintHuffmanCode(HuffmanCode hc,HuffmanTree ht,int n){
int i;
for(i=1;i<=n;i++){
cout<<ht[i].weight<<":"<<hc[i]<<endl;
}
}
void main(){
HuffmanTree ht;
HuffmanCode hc;
int n=8,w[]={2,4,6,3,7,45,32,56};
CreateHuffmanTree(ht,w,n);
CreateHuffmanCode(hc,ht,n);
PrintHuffmanCode(hc,ht,n);
}