该篇文章主要求解哈夫曼编码
代码示例:
#include <iostream>
using namespace std;
const int MaxLeng=50; //哈夫曼编码最大长度
const int MaxSize=100; //最多总结点个数
template <typename T>
struct HTNode //哈夫曼树结点类
{ T data; //结点值
double weight; //权值
int parent; //双亲结点
int lchild; //左孩子结点
int rchild; //右孩子结点
};
struct HCode //哈夫曼编码类型
{ char cd[MaxLeng]; //存放当前结点的哈夫曼码
int start; //用cd[start..n0]存放哈夫曼码
};
template <typename T>
class HuffmanClass //哈夫曼树类模板
{
int n0; //权值个数
HTNode<T> ht[MaxSize]; //存放哈夫曼树
HCode hcd[MaxSize]; //存放哈夫曼编码
public:
void Setvalue(T *str,double d[],int m); //设置初值
void CreateHT(); //构造哈夫曼树
void CreateHCode(); //根据哈夫曼树求哈夫曼编码
void DispHCode(); //输出哈夫曼编码
};
template <typename T>
void HuffmanClass<T>::Setvalue(T *str,double d[],int m) //设置初值
{
int i;
n0=m;
for (i=0;i<m;i++)
{
ht[i].data=str[i];
ht[i].weight=d[i];
}
}
template <typename T>
void HuffmanClass<T>::CreateHT() //构造哈夫曼树
{
int i,k,lnode,rnode;
double min1,min2;
for (i=0;i<(2*n0-1);i++) //所有结点的相关域置初值-1
{
ht[i].parent=-1;
ht[i].lchild=-1;
ht[i].rchild=-1;
}
for (i=n0;i<(2*n0-1);i++) //构造哈夫曼树,仅求非叶子结点
{
min1=min2=32767.00;
lnode=rnode=-1; //lnode和rnode为两个权重最小的结点位置
for (k=0;k<=(i-1);k++) //在ht数组中找权值最小的两个结点
if (ht[k].parent==-1) //只在尚未构造二叉树的结点中查找
{
if (ht[k].weight<min1)
{
min2=min1; rnode=lnode;
min1=ht[k].weight;
lnode=k;
}
else if (ht[k].weight<min2)
{
min2=ht[k].weight;
rnode=k;
}
}
ht[lnode].parent=i; ht[rnode].parent=i;
ht[i].weight=ht[lnode].weight+ht[rnode].weight;
ht[i].lchild=lnode;
ht[i].rchild=rnode; //ht[i]作为双亲结点
}
}
template <typename T>
void HuffmanClass<T>::CreateHCode() //根据哈夫曼树求哈夫曼编码
{
int i,f,c;
for (i=0;i<n0;i++) //遍历下标从0到n0-1的叶子结点
{
hcd[i].start=n0;
c=i; f=ht[i].parent;
while (f!=-1) //循环直到无双亲结点即到达树根结点
{
if (ht[f].lchild==c) //当前结点是双亲结点的左孩子结点
{
hcd[i].cd[hcd[i].start]='0';
hcd[i].start--;
}
else //当前结点是双亲结点的右孩子结点
{
hcd[i].cd[hcd[i].start]='1';
hcd[i].start--;
}
c=f; f=ht[f].parent; //再对双亲结点进行同样的操作
}
hcd[i].start++; //start指向哈夫曼编码最开始字符
}
}
template <typename T>
void HuffmanClass<T>::DispHCode() //输出哈夫曼编码
{
int i,j;
for (i=0;i<n0;i++)
{
cout << " " << ht[i].data << ": ";
for (j=hcd[i].start;j<=n0;j++)
cout << hcd[i].cd[j];
cout << endl;
}
}
void main()
{
HuffmanClass<char> hf;
int m=8;
char str[]="abcdefgh";
double d[]={0.07,0.19,0.02,0.06,0.32,0.03,0.21,0.10};
hf.Setvalue(str,d,m); //设置初值
hf.CreateHT(); //建立哈夫曼树
hf.CreateHCode(); //建立哈夫曼编码
cout << "输出哈夫曼编码如下:\n";
hf.DispHCode(); //输出哈夫曼编码
cout << "main结束,销毁所有建立的对象\n";
}