【SSL】1409【树】哈夫曼树(三)

【SSL】1409【树】哈夫曼树(三)

Time Limit:1000MS
Memory Limit:65536K

Description

根据传送的一串字符出现的频率,设置其相应的哈夫曼编码

Input

一串字符

Output

哈夫曼编码(按照中序遍历输出各个字母和编码,中间用冒号分开,按照左子树根节点的频率小于等于右子树根节点的频率的次序构造,若频率相同,左子树根节点的首次出现位置小于右子树根节点的首次出现位置)

Sample Input

XINNNMM

Sample Output

N:0
M:10
X:110
I:111

思路

【SSL】1407【树】哈夫曼树(一)【SSL】1408【树】哈夫曼树(二)的升级版

计算频率
构造哈夫曼树
中序遍历递归输出

构造哈夫曼树的基本思想是要让权大的叶子离根最近。
具体作法是:
   (1)根据给定的n个权值{w1,w2,…,wn},构造n棵二叉树的集合F={T1,T2,…,Tn},其中每棵二叉树中均只含一个带权值为wi的根结点,其左、右子树为空树;
   (2)在F中选取其根结点的权值为最小的两棵二叉树,分别作为左、右子树构造一棵新的二叉树,并置这棵新的二叉树根结点的权值为其左、右子树根结点的权值之和;
   (3)从F中删去这两棵树,同时加入刚生成的新树;
   (4)重复(2)和(3)两步,直到F中只含一棵树为止。
   从上述算法中可以看出,F实际上是森林,该算法的思想是不断地进行森林F中的二叉树的“合并”,最终得到哈夫曼树。
   实际上,哈夫曼算法的实现与实际问题所采用的存储结构有关。现假设用数组F来存储哈夫曼树,其中第i个数组元素F[i]是哈夫曼树中的一个结点,其地址为i,有3个域,Data域存放该结点的权值,lChild域和rChild域分别存放该结点左、右子树的根结点的地址(下标)。在初始状态下: F[i].Data=Wi,F[i].lChild=F[i].rChild=0,i=1,2,…,n。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
char ans[2010]="",str[2010];
struct tree
{
    
    
	char zm;//字母 
	int s,l,r;//s权值,l左子树地址,r右子树地址 
}a[2010];
int b[2010],wz[2010];//b:a中地址,wz:某字母a中的位置 
bool cmp(int x,int y)
{
    
    
	if(a[x].s==a[y].s)
		return x>y;//比较首次出现的顺序 
	return a[x].s>a[y].s;
}
void print(int x,int dep)//中序遍历输出 
{
    
    
	if(a[x].l==0&&a[x].r==0)//叶子节点 
		printf("%c:%s\n",a[x].zm,ans);
	if(a[x].l>0)
		ans[dep+1]=0,ans[dep]='0',print(a[x].l,dep+1);//输出左子树
	if(a[x].r>0)
		ans[dep+1]=0,ans[dep]='1',print(a[x].r,dep+1);//输出右子树
	return;
}
int main()
{
    
    
	int i,j,w,len=0;
	memset(wz,0,sizeof(wz));
	scanf("%s",&str);
	for(i=0;str[i];i++)
	{
    
    
		if(wz[str[i]])
			a[wz[str[i]]].s++;
		else
		{
    
    
			wz[str[i]]=++len,b[len]=wz[str[i]];
			a[wz[str[i]]].s=1,a[wz[str[i]]].zm=str[i],a[wz[str[i]]].l=a[wz[str[i]]].r=0;
		}
	}
	sort(b+1,b+len+1,cmp);//排序 
	for(i=len;i>1;i--)
	{
    
    
		w=len+len-i+1;
		a[w].s=a[b[i]].s+a[b[i-1]].s;//合并 
		a[w].l=b[i],a[w].r=b[i-1];
		for(j=i-1;j>0&&cmp(w,b[j]);b[j+1]=b[j],j--);//插入排序 
		b[j+1]=w;
	}
	print(len+len-1,0);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_46975572/article/details/113113414