哈夫曼编码C程序及演示结果

来源:互联网 发布:网络教育自我鉴定200字 编辑:程序博客网 时间:2024/06/07 10:48

哈夫曼编码

功能简介:首先输入信源符号的个数,然后输入各个信源符号的概率。(概率之和等于1)

主程序                                                         李松林

#include<stdio.h>                              湖北师范学院

#include<math.h>

#define G 20

void qiumazi(int M);  //求码字

 

struct abc

{

 int b;

 int d[G];

 //float c[G];

 float num;

}D[G],E;

 

float a[G]={0},f[G],tmp=0,m[G]={0},k=0,H=0;

int K[G]={0},i,j,N,s[G][G]={0},cs=0;

 

void main()

{

loop:printf("请输入信源符号个数N");

 scanf("%d",&N);

 for(i=0;i<N;i++)

 {

   scanf("%f",&a[i]);

   tmp+=a[i];

 }

 if(tmp<0.9999||tmp>1.0001)

 {

   printf("输入的数据不符合要求,请重新输入\n");

   tmp=0;

   goto loop;

 }

 else

 {

for(i=0;i<N-1;i++)    //从大到小进行排序

   for(j=i+1;j<N;j++)

   {

if(a[i]<a[j])

{

 tmp=a[i];

 a[i]=a[j];

 a[j]=tmp;

}

   }

for(i=0;i<N;i++)

{

 D[i].b=1;

 D[i].d[0]=i;

 //D[i].c[0]=a[i];

 D[i].num=a[i];

}

 

    for(i=0;i<N;i++)

{

m[i]=-log10(a[i])/log10(2.0);  //求出-log p(ai)并保存在数组m

}

 

    qiumazi(N);

 

    for(i=0;i<N;i++)

{

 H+=a[i]*m[i];  //求信源熵

 k+=a[i]*K[i];  //求平均码长

}

printf("信源消息符号ai  符号概率p(ai)    码长Ki      二元码字\n");

for(i=0;i<N;i++)

{

      printf("     a%d           %-4.2f              %d           ",i+1,a[i],K[i]);

  for(j=K[i];j>0;j--)

printf("%d",s[i][j-1]);

  printf("\n");

}

printf("信源熵H=%5.3f bit/符号    费诺码的平均码长k=%5.3f 码元/符号    编码效率n=%4.1f%% \n",H,k,100*(H/k));

 }

}

 

void qiumazi(int M)  //求码字

{

  for(i=0;i<M-1;i++)

  for(j=i+1;j<M;j++)

  if(D[i].num<D[j].num)

  {

   E=D[i];

   D[i]=D[j];

   D[j]=E;

  }

 

  for(i=0;i<D[M-2].b;i++)

  {

   j=D[M-2].d[i];

   s[j][K[j]]=0;

   K[j]+=1;

  }

 

  for(i=0;i<D[M-1].b;i++)

  {

   j=D[M-1].d[i]; 

   s[j][K[j]]=1;

   K[j]+=1;

  }

 

  D[M-2].num+=D[M-1].num;

  for(i=0;i<D[M-1].b;i++)

  {

   D[M-2].d[i+D[M-2].b]=D[M-1].d[i];

  // D[M-2].c[i+D[M-2].b]=D[M-1].c[i];

  }

  D[M-2].b+=D[M-1].b;

 

/**********这样可以获得较小的码方差************/

 /* E=D[0];

  D[0]=D[M-2];

  D[M-2]=E;*/

/**********码方差越小编码的质量越好***********/

 

  M--; 

  if(M>1)

  {

   cs++;

   qiumazi(M);

  }

}

 

第一次输入:5  0.4  0.2  0.2  0.1  0.1

结果是:

 

第二次输入:6  0.32  0.22  0.18  0.16  0.08  0.04

结果是:

 

第三次输入:7  0.20  0.19  0.18  0.17  0.15  0.10  0.01

结果是:

 

1 0
原创粉丝点击