SSL_1407【【树】哈夫曼树(一)】

【树】哈夫曼树(一)

题目

假设用于通信的电文仅由8个字母组成,字母在电文中出现的频率分别为7、19、2、6、32、3、21、10。试为这8个字母设计哈夫曼编码。如果用二进制数表示这8个字母的编码方案.(请按照左子树根节点的权小于等于右子树根节点的权的次序构造

Input

第一行为字母的个数n;
第二行至第n+1行分别为各个字母在电文中出现的频率。

Output

按照中序遍历输出各个编码

Sample Input

8
7
19
2
6
32
3
21
10

Sample Output

19:00
21:01
2:10000
3:10001
6:1001
7:1010
10:1011
32:11

解析

啊不开SPJ就很烦的
烦又能怎么样呢,我又不会写SPJ
哈夫曼树,是一个最优叶子节点划分问题,常被用于压缩
不得不说这个算法是真的冷门,全洛谷只有一道荷马史诗是哈夫曼题

code:

#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
int n,x[10010],r,j;
struct tree{
    
    int s,l,r;}a[100010];
char q[100010];
inline void dfs(int x,int dep)
{
    
    
	if((!a[x].l)&&(!a[x].r))
	{
    
    
		printf("%d:",a[x].s);
		for(register int i=1;i<dep;++i)putchar(q[i]);
		putchar('\n');
		return;
	}
	if(a[x].l)q[dep]='0',dfs(a[x].l,dep+1);
	if(a[x].r)q[dep]='1',dfs(a[x].r,dep+1);
}
inline bool cmp(int x,int y){
    
    return a[x].s>a[y].s;}
int main()
{
    
    
	scanf("%d",&n);
	for(int i=1;i<=n;++i)scanf("%d",&a[i].s),x[i]=i;
	sort(x+1,x+n+1,cmp);
	for(int i=n;i>1;--i)
	{
    
    
		r=(n<<1)-i+1;
		a[r].s=a[x[i]].s+a[x[i-1]].s,a[r].l=x[i],a[r].r=x[i-1];
		for(j=i-1;j&&a[r].s>a[x[j]].s;--j)x[j+1]=x[j];
		x[j+1]=r;
	}
	dfs((n<<1)-1,1);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zhanglili1597895/article/details/115098745