1. 程式人生 > >簡單哈弗曼編碼

簡單哈弗曼編碼

//此程式碼是資料結構的原始模板,可以剛接觸或考研時借鑑下,不適於刷題
#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;
}