简单哈弗曼编码

//此代码是数据结构的原始模板,可以刚接触或考研时借鉴下,不适于刷题
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int s1,s2;
typedef struct node
{
	int weight;
	int parent;
	int lchild;
	int rchild;
}tree,*bitree;
void selet(tree ht[],int x)
{
	int i,min1='0x3f',min2='0x3f';
	for(i=1;i<=x;i++)
	{
       if(min1>ht[i].weight&&ht[i].parent==0)
	   {
	     min1=ht[i].weight;
	   }
	}
   for(i=1;i<=x;i++)
	{
       if(min1==ht[i].weight&&ht[i].parent==0)
	   {
	     s1=i;
		 ht[i].parent=-1;
		 break;
	   }
	}
	for(i=1;i<=x;i++)
	{
       if(min2>ht[i].weight&&ht[i].parent==0)
	   {
	     min2=ht[i].weight;
	   }
	}
		for(i=1;i<=x;i++)
	{
       if(min2==ht[i].weight&&ht[i].parent==0)
	   {
	     s2=i;
		 break;
	   }
	}
	ht[s1].parent=0;
	if(min1==min2)
	{
		int r=s1;
		s1=s2;
		s2=r;
	}
	
}
bitree crthuffmantree(tree ht[],int w[],int n)//构造哈弗曼树
{
	for(int i=1;i<=n;i++)
	{
		ht[i].weight=w[i];
		ht[i].parent=0;
		ht[i].lchild=0;
		ht[i].rchild=0;
	}
	int m=2*n-1;
	for(i=n+1;i<=m;i++)
	{
		ht[i].weight=0;
	    ht[i].parent=0;
		ht[i].lchild=0;
		ht[i].rchild=0;
	}
	for(i=n+1;i<=m;i++)
	{
		selet(ht,i-1);
	    ht[i].weight=ht[s1].weight+ht[s2].weight;
	    ht[s1].parent=i;
		ht[s2].parent=i;
		ht[i].lchild=s1;
		ht[i].rchild=s2;
	}
	return ht;
}
typedef char *huffmancode[300];
void crthuffmancode(tree ht[],huffmancode hc,int n,char is[])
{
	char *cd;
	int start,c,p,i;
	cd=(char*)malloc(n*sizeof(char));
	cd[n-1]='\0';
	for(i=1;i<=n;i++)
	{
		start=n-1;
		c=i;
		p=ht[i].parent;
		if(p==0)
		{
		hc[i]=(char*)malloc((n-start)*sizeof(char));
		strcpy(hc[i],"1");
		}
		else
		{
		while(p!=0)
		{
			--start;
			if(ht[p].lchild==c)
				cd[start]='0';
			else
				cd[start]='1';
			c=p;
			p=ht[p].parent;
		}
		hc[i]=(char*)malloc((n-start)*sizeof(char));
		strcpy(hc[i],&cd[start]);
		}
	}
	for(i=1;i<=n;i++)
	printf("%c:%s\n",is[i],hc[i]);
	free(cd);
}
int main()
{
	char english[10000],is[100];
	huffmancode Huffmancode;
	printf("请输入一字符串可利用哈弗曼树原理求出字符串中各字符的哈弗曼编码:\n");
	scanf("%s",english);
	int len=strlen(english);
	int i,j,ajj[300];
	ajj[0]=0;
	ajj[1]=1;
	is[1]=english[0];
	int ans=1;
	for(i=1;i<len;i++)
	{
		for(j=1;j<=ans;j++)
		{
		if(english[i]==is[j])
		{
			ajj[j]++;
			break;
		}
		}
		if(j==ans+1)
		{
			is[ans+1]=english[i];
			ajj[ans+1]=1;
			ans++;//表示有多少个不同的字母
		}
	}
	tree hufu[400];
	bitree ht1;
	hufu[0].weight=0;
	hufu[0].parent=0;
	hufu[0].lchild=0;
	hufu[0].rchild=0;
	ht1=crthuffmantree(hufu,ajj,ans);
	crthuffmancode(ht1,Huffmancode,ans,is);
	return 0;
}


		
	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值