Huffman-哈夫曼树-数据结构

哈夫曼树

#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);

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值