哈夫曼编码

【问题描述】

读入n个字符所对应的权值,自底向上构造一棵哈夫曼树,自顶向下生成每一个字符对应的哈夫曼编码,并依次输出。

【输入形式】

输入的第一行包含一个正整数n,表示共有n个字符需要编码。其中n不超过100。

第二行中有n个用空格隔开的正整数,分别表示n个字符的权值。

【输出形式】

共n行,每行一个字符串,表示对应字符的赫夫曼编码。

【注意】保证每次左子树比右子树的权值小;如出现相同权值的,则先出现的在左子树。

【样例输入】

8
5 29 7 8 14 23 3 11

【样例输出】

0001
10
1110
1111
110
01
0000
001

#include<iostream>
#include<stdlib.h>
#include<cstring>
using namespace std;

struct Huffman
{
	int weight;
	int parent;
	int LChild;
	int RChild; 
};

struct HuffmanCode
{
	char bits[100];
};

void Select(Huffman T[],int n,int &s1,int &s2)
{
	int min=0,i;
	for(i=1;i<=n;i++)
	{
		if(T[i].parent==0)
		{
			min=i;
			break;
		}
	}
	for(i=1;i<=n;i++)
	{
		if(T[i].parent==0)
		{
			if(T[i].weight<T[min].weight)
			{
				min=i;
			}
		}
	}
	s1=min;
	//
	for(i=1;i<=n;i++)
	{
		if(T[i].parent==0&&i!=s1)
		{
			min=i;
			break;
		}
	}
	for(i=1;i<=n;i++)
	{
		if(T[i].parent==0&&i!=s1)
		{
			if(T[i].weight<T[min].weight)
			{
				min=i;
			}
		}
	}
	s2=min;
}

void Init(Huffman T[],int w[],int n)
{
	int i,s1,s2;
	for(i=1;i<=n;i++)
	{
		T[i].weight=w[i];
		T[i].parent=0;
		T[i].LChild=0;
		T[i].RChild=0;
	}
	for(i=n+1;i<=2*n-1;i++)
	{
		T[i].weight=0;
		T[i].parent=0;
		T[i].LChild=0;
		T[i].RChild=0;
	}
	for(i=n+1;i<=2*n-1;i++)
	{
		Select(T,i-1,s1,s2);
		T[i].weight=T[s1].weight+T[s2].weight;
		T[s1].parent=i;
		T[s2].parent=i;
		T[i].LChild=s1;
		T[i].RChild=s2;
	}
}

void CreateCode(Huffman T[],HuffmanCode ST[],int n)
{
	int c,start,p,i;
	char cd[1000];
	//cd[n-1]='\0';
	for(i=1;i<=n;i++)
	{
		start=n-1;
		c=i;
		p=T[i].parent;
		while(p!=0)
		{
			start--;
			if(T[p].LChild==c)
			cd[start]='0';
			else
			cd[start]='1';
			c=p;
			p=T[p].parent;
		}
		strcpy(ST[i].bits,&cd[start]);
	}
}

int main()
{
	int n,i;
	int w[1000];//用来存放权值 
	Huffman T[1000];
	HuffmanCode ST[1000];
	cin>>n;
	for(i=1;i<=n;i++)
	cin>>w[i];
	Init(T,w,n);
	CreateCode(T,ST,n);
	cout<<endl;
	for(i=1;i<=n;i++)
	cout<<ST[i].bits<<endl;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值