哈夫曼编码

 

#include<iostream>
 
using namespace std;
#define Max 15
typedef struct
{
 unsigned weight;
 unsigned p;
 unsigned lc;
 unsigned rc;
}HTNode;
int findmin(HTNode* huf,int n,int m);
int main()
{

 int i,j=0,k=0;
 int m=-1;
 int str[8][5];
 int str2[8][5];

 cout<<"               Problem                  "<<endl;
 cout<<"   某系统在通信联络中只可能出现八种字符(A,B,C,D,E,F,G,H),其使用概率分别为0.05、0.29、0.07、0.08、0.14、0.23、0.03、0.11,如何设计这些字符的二进制编码,以使通信中总码长尽可能短?"<<endl;
 int ar[8]={ 5, 29, 7, 8, 14, 23, 3, 11};


 HTNode huf[16];
 int min1,min2;
 for(i=0;i<8;i++)
  huf[i].weight=ar[i];
 for(i=0;i<16;i++)
  huf[i].p=huf[i].lc =huf[i].rc =0;

 for(i=8;i<15;i++)
 {
  min1=findmin(huf,i,m);
  m=min1;
  min2=findmin(huf,i,m);
  huf[i].weight =huf[min1].weight +huf[min2].weight ;
  huf[i].lc =min1;
  huf[i].rc =min2;
  huf[min1].p=huf[min2].p=i;
  m=-1;
 }
 huf[i-1].p=15;
 cout<<"数组方式存储的树如下: "<<endl;
 cout<<"权值    "<<"双亲节点   "<<"左孩子节点  "<<" 右孩子节点    "<<endl;
 for(i=0;i<15;i++)
  cout<<huf[i].weight <<"          "<<huf[i].p<<"            "<<huf[i].lc <<"          "<<huf[i].rc <<endl;
 
 for(i=0;i<8;i++)
 {
  k=i;
  while(k<14)
  {
   m=k;
   k=huf[k].p;
   if(m==huf[k].lc)
    str[i][j++]=0;
   else
    str[i][j++]=1;
  }
  str[i][j]=-1;
  j=0;
 }
 
  
 for(i=0;i<8;i++)
 {
  j=0;
  while(str[i][j]!=-1)
   j++;
  for(m=0;m<j;m++)
   str2[i][m]=str[i][j-1-m];
  str2[i][m]=-1;
 }
 char ch='A';
 cout<<"各字符的赫夫曼编码是: "<<endl;
 for(i=0;i<8;i++)
 {
  j=0;
  cout<<char(ch+i)<<" : ";
  while(str2[i][j]!=-1)
   cout<<str2[i][j++]<<" ";
  cout<<endl;
 }
 cout<<"最短的通信总码长度为 : "<<endl;
 double sum=0;
 for(i=0;i<8;i++)
 {
  j=0;
  while(str[i][j]!=-1)
   j++;
  sum+=ar[i]*j;
 }
 cout<<sum/100<<endl;

 return 0;
}
int findmin(HTNode* huf,int n,int m)
{
 int i,min,j;
 for(i=0;i<=n;i++)
  if(huf[i].p==0&&i!=m)
  {min=i;break;}
 for( j=i;j<=n;j++)
  if(huf[j].p==0)
   if(huf[j].weight <huf[min].weight &&j!=m)
    min=j;
 return min;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值