哈夫曼树

该篇文章主要求解哈夫曼编码

代码示例:

#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";
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值