本文没有论述哈弗曼编码的原理、过程。只是将其实现过程现于纸上,为更多朋友在紧急的时候提供方便。忘广大朋友提出批评与指正,后续将不断撰写常用的算法源码
#include<stdio.h>
#include<stdlib.h>
#define MAXVALUE 10
typedef struct HTNode{
float weight; //结点权重
int parent; //当前结点的父节点
int LChild; //当前结点的左子节点
int RChild; //当前结点的右子节点
}HTNode;
void select(HTNode hTree[],int n,int *s1,int *s2){//选择较小的两个结点,这里将s1和s2的地址传递过去
int i,j;
float min1,min2;
min1=min2=MAXVALUE;//要找两个较小的数
for(i=0;i<n;i++){ //在树中找最小结点
if(min1>hTree[i].weight&&hTree[i].parent==-1){//注意判断条件,hTree[i].parent==-1表示该节点还未被选过
*s1=i;
}
}
for(j=0;j<n;j++){ //在树中找次最小结点
if(min2>hTree[j].weight&&hTree[j].parent==-1&&(*s1)!=j){
*s2=j;
}
}
}
void crtHuffmanTree(HTNode hTree[],float p[],int r){//创建哈弗曼树
int i,s1,s2,m;
m=2*r-1;//有r个叶子结点,当整棵树构建完毕时,结点总数为m个
for(i=0;i<r;i++){ //哈弗曼树的初态
hTree[i].weight=p[i];
hTree[i].LChild=-1;
hTree[i].parent=-1;
hTree[i].RChild=-1;
}
for(i=r;i<m;i++){
select(hTree,i-1,&s1,&s2);//在树中找两个权值最小的,将下标值赋给s1,s2;
hTree[i].weight=hTree[s1].weight+hTree[s2].weight;
hTree[s1].parent=i;
hTree[s2].parent=i;
hTree[i].LChild=s1;
hTree[i].RChild=s2;
hTree[i].parent=-1;
}
for(i=0;i<m;i++){
printf("%lf \n",hTree[i].weight);
}
printf("创建哈弗曼树完毕\n");
}
void main(){
HTNode hTree[2*4-1] ;//测试,假设有4个节点
float p[4]={2.00/5.00,1.00/5.00,1.00/5.00,1.00/5.00};//分别是这四个结点的权重
crtHuffmanTree(hTree,p,4);
}