一个可直接用的赫夫曼源代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_NUM 100

typedef char ElemType; 
typedef struct HTNode
{ 
   ElemType elem;
   int m_weight; 
   int parent,lchild,rchild; 
}HTNode,*HuffmanTree; 

typedef char** HuffmanCode; 
typedef int Status; 
typedef struct weight
{
  char elem; 
  unsigned int m_weight; 
}Weight; 

void Huffman(HuffmanTree *HT,HuffmanCode *HC,Weight *w,int n); 
void Select(HuffmanTree HT,int n,int *s1,int *s2); 
void Output(HuffmanTree HT,HuffmanCode HC,int n,char *ch); 


int main(void) 
{ 
  HuffmanTree HT; 
  HuffmanCode HC; 
  Weight *w; 
  char c[MAX_NUM]={0},c_copy[MAX_NUM]={0};
  int frequence[MAX_NUM];
  int i,num=0,j,k,l;   
  int daxie[26]={0},xiaoxie[26]={0}; 
  error:
  printf("请输入需要编码的字符串:"); 
  scanf(" %s",&c);
  for(j=0;c[j]>0;j++)
  c_copy[j]=c[j];
  for(j=0;c[j]>0;j++)
  {
  	if(c[j]>='A'&&c[j]<='Z')
  	++daxie[c[j]-'A'];
  	else if(c[j]>='a'&&c[j]<='z')
  	++xiaoxie[c[j]-'a'];
  	else
  	{printf("输入中含有非字母元素!请重新输入!\n\n");
  	for(j=0;j<=26;j++)
  	{
  		daxie[j]=0;xiaoxie[j]=0;
  	}
  	goto error;}
  }   
  w=(Weight *)malloc(j*sizeof(Weight)); 
  for(k=0;k<=j;k++)
  {
  	if(c[k]>='A'&&c[k]<='Z')
  	frequence[k]=daxie[c[k]-'A'];
  	else if(c[k]>='a'&&c[k]<='z')
  	frequence[k]=xiaoxie[c[k]-'a'];
  }
  for(i=0;i<j;i++)
  {
    int q=i;
	if(q>0)
	{
		for(q;q>=0;)
		{
			q=q-1;
			if(c[i]==c[q])
			{c[i]=0;
			frequence[i]=0;}
		}
	}
	if(c[i]!=0&&frequence[i]!=0)
	{
		w[num].elem=c[i]; 
        w[num].m_weight=frequence[i];
		num++; 
	}	
  } 
  Huffman(&HT,&HC,w,num); 
  Output(HT,HC,num,c_copy); 
  return 0; 
} 


void Huffman(HuffmanTree *HT,HuffmanCode *HC,Weight *w,int n)
{ 
  int i,m,s1,s2,start,c,f; 
  char *cd; 
  if(n<=1)
  return; 
  m=2*n-1; 
  (*HT)=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
  for(i=1;i<=n;++i)
  {
  	 (*HT)[i].elem=w[i-1].elem; 
     (*HT)[i].m_weight=w[i-1].m_weight; 
     (*HT)[i].parent=(*HT)[i].lchild=(*HT)[i].rchild=0; 
  }
  for(;i<=m;++i)
  { 
    (*HT)[i].elem='0'; 
    (*HT)[i].m_weight=(*HT)[i].parent=(*HT)[i].lchild=(*HT)[i].rchild=0; 
  } 
  for(i=n+1;i<=m;++i)
  { 
    Select(*HT,i-1,&s1,&s2); 
    (*HT)[s1].parent=i;(*HT)[s2].parent=i; 
    (*HT)[i].lchild=s1;(*HT)[i].rchild=s2; 
    (*HT)[i].m_weight=(*HT)[s1].m_weight+(*HT)[s2].m_weight; 
  } 
  (*HC)=(HuffmanCode)malloc(n*sizeof(char*)); 
  cd=(char *)malloc(n*sizeof(char)); 
  cd[n-1]='\0'; 
  for(i=1;i<=n;++i)
  { 
     start=n-1; 
     for(c=i,f=(*HT)[i].parent;f!=0;c=f,f=(*HT)[f].parent)
     {
     	if((*HT)[f].lchild==c) cd[--start]='0'; 
        else cd[--start]='1'; 
     }
     (*HC)[i]=(char *)malloc((n-start)*sizeof(char));
     strcpy((*HC)[i],&cd[start]); 
  } 
} 


void Select(HuffmanTree HT,int n,int *s1,int *s2) 
{ 
  int i; 
  (*s1)=(*s2)=0; 
  for(i=1;i<=n;i++)
  { 
      if(HT[i].m_weight<HT[(*s2)].m_weight&&HT[i].parent==0&&(*s2)!=0)
      {
    	  if(HT[i].m_weight<HT[(*s1)].m_weight)
    	  {
	      	  (*s2)=(*s1); 
  			  (*s1)=i; 
	      }
      	  else (*s2)=i; 
      }
      if(((*s1)==0||(*s2)==0)&&HT[i].parent==0)
	  {
		  if((*s1)==0) (*s1)=i; 
      	  else if((*s2)==0)
		    {
  			  if(HT[i].m_weight<HT[(*s1)].m_weight)
			   { 
			     (*s2)=(*s1); 
			     (*s1)=i; 
			   } 
  			  else (*s2)=i; 
  	   	    } 
      }
   } 
   if((*s1)>(*s2))
   { 
     i=(*s1); 
 	 (*s1)=(*s2); 
	 (*s2)=i; 
   } 
} 


void Output(HuffmanTree HT,HuffmanCode HC,int n,char *ch) 
{ 
    int i,j; 
    printf("\n  <各个字符对应的赫夫曼编码表>\n 序号\t 元素\t 权重\t 赫夫曼编码\n"); 
    for(i=1;i<=n;i++) 
    printf("  %d\t  %c\t  %d\t    %s\n",i,HT[i].elem,HT[i].m_weight,HC[i]); 
    printf("\n输入字符串的赫夫曼编码为:");
    for(i=0;ch[i]!=0;i++)
    {
    	j=1;
    	for(j;j<=n;j++)
    	{
	    	if(ch[i]==HT[j].elem)
    		printf("%s ",HC[j]);
	    }
    }
    printf("\n\n"); 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值