1. 程式人生 > >哈夫曼編碼C程式及演示結果

哈夫曼編碼C程式及演示結果

哈夫曼編碼

功能簡介:首先輸入信源符號的個數,然後輸入各個信源符號的概率。(概率之和等於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

結果是: