贴个代码,仅供参考。
感觉三点比较重要:
1、熟悉指针、引用、内存分配。
2、清楚创建树与编码过程。该过程中有两点比较重要:a.创建叶子节点以外的节点时,是怎么select以及如何建立父子结点关系。b、在编码的时候是如何从叶子节点出发,一步一步查找的。
3、理解为何这样编码可以缩短编码长度。
#include<stdlib.h>
#include<cstring>
#include<iostream>
using namespace std;
#define MAXCODE 1000 //赫夫曼代码的最大长度
#define MAXWEIGHT 3000//定义最大权值
typedef struct {
char c;
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTnode,*HUffmantree;//动态分配数组储存赫夫曼编码表
typedef char ** HUffmancode;//动态储存和夫曼编码
void select(HUffmantree HT,int t,int &s1,int &s2)//select函数用于找出权值最小的两个结点
{
int i,m,n;
m=n=MAXWEIGHT;
for(i=1;i<=t;i++)
{
if(HT[i].parent==0 && (HT[i].weight<m || HT[i].weight<n))
if(m<n)
{
n=HT[i].weight; s2=i;
}
else
{
m=HT[i].weight;
s1=i;
}
}
if(s1>s2)
{
i=s1;
s1=s2;
s2=i;
}
}
void HUffmanCreate(HUffmantree &HT,int n)
{
HUffmantree p;
int i,m;
int s1,s2;
if(n<=1)
return;
m=2*n-1;
HT=(HUffmantree)malloc((m+1)* sizeof(HTnode));
for(p = HT+1,i=1;i<=n;++i,++p)//初始化叶子节点。
{
cout<<"请输入第 "<<i<<" 个字符以及它的权重:"<<endl;
cin>>p->c>>p->weight;
p->lchild=0;
p->parent=0;
p->rchild=0;
}
for(;i<=m;++i,++p)//初始化叶子节点以外的的其他节点
{
p->weight=0;
p->lchild=0;
p->parent=0;
p->rchild=0;
}
//创建赫夫曼树。
for(i=n+1;i<=m;++i)
{
select(HT,i-1,s1,s2);
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight + HT[s2].weight;
}
}
//从叶子节点到根逆向求每一个字符的赫夫曼码
void HUffmancoding(HUffmantree HT,HUffmancode &HC,int n)
{
char *cd;
int i,c,f,start;
HC=(HUffmancode)malloc((n+1)*sizeof(char *));
cd=(char *)malloc(n*sizeof(char));
cd[n-1]='\0';
for(i=1;i<=n;i++)
{
start=n-1;
for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)
{
if(HT[f].lchild == c)
cd [--start] = '0';
else
cd [--start] = '1';
HC[i] = (char *)malloc((n-start)*sizeof(char ));
strcpy_s(HC[i],n-start,&cd[start]);
}
}
free(cd);
}
int main()
{
HUffmantree hf;
HUffmancode hc;
int n,i;
cout<<"请输入字母数: ";
cin>>n;
HUffmanCreate(hf,n);
HUffmancoding(hf,hc,n);
cout<<"---------------------------------"<<endl;
for(i=1;i<=n;i++)
cout<<"字符:"<<hf[i].c<<"\t\t"<<"Huffmancode编码:"<<hc[i]<<endl;
cout<<"---------------------------------"<<endl;
return 0;
}