C语言压缩程序 Huffman Coding霍夫曼编码

/1.程序目的:通过huffman最优二叉树寻找最优的压缩码,并输出。
i)码字具有前缀性质。
ii)使用频率较高的字符用较短的码字(01串)代替。
2. 题目:在一个文件中,几个字符出现的频率分别是2%、3%、4%、7%、8%,
找出最优的对应的01串.
3.编写:tq
4.时间:2009年09月27日 19:34:17
***************************/

/*1.程序目的:通过huffman最优二叉树寻找最优的压缩码,并输出。
              i)码字具有前缀性质。
              ii)使用频率较高的字符用较短的码字(01串)代替。
  2.    题目:在一个文件中,几个字符出现的频率分别是2%、3%、4%、7%、8%,
              找出最优的对应的01串.
  3.编写:tq
  4.时间:2009年09月27日 19:34:17****************************/

 
/*以下是对数组进行排序的子函数,利用快速排序*/
/***********************************************************************/
void run(int* pData,int left,int right)
{
  int i,j;
  int middle,iTemp;
  i = left;
  j = right;
  middle=pData[(left+right)/2]; /* 求中间值 */
  do{
    while((pData[i]<middle)&&(i<right))/* 从左扫描大于中值的数 */
      i++;     
    while((pData[j]>middle) && (j>left))/* 从右扫描大于中值的数  */
      j--;
    if(i<=j)/* 找到了一对值  */
    {
      /* 交换  */
      iTemp = pData[i];
      pData[i] = pData[j];
      pData[j] = iTemp;
      i++;
      j--;
    }
  }while(i<=j);/* 如果两边扫描的下标交错,就停止(完成一次)*/

  /*当左边部分有值(left<j),递归左半边*/
  if(left<j)
    run(pData,left,j);
  /*当右边部分有值(right>i),递归右半边*/
  if(right>i)
    run(pData,i,right);
}

 

void QuickSort(int* pData,int Count)
{
  run(pData,0,Count-1);
}
/**********************************************************************/

 

void main()
{
    int s[5]={4,3,2,7,8},
        s1[5]={4,3,2,7,8},
        i,j,k,ii,jj,tree[27],father,huf_code[3];

    /*对tree进行初始化*/
    for(i=0;i<27;i++)
        tree[i]=0;


/*******************************************************************/
    j=0;
    do
    {
        i=0;
        QuickSort(s,5);/*每次做循环之前都对s数组排序,
                         确保最小的两个在前面*/

        printf("%5d,%5d,%5d,%5d,%5d,\n",s[0],s[1],s[2],s[3],s[4]);

        father=s[0]+s[1];/*合并两颗最小的的树*/

        /*给tree数组赋值,使之最终具有二叉树的性质。
          每三个一组分别是:本身,父亲,左(0)右(1)*/
        tree[j]=s[0];
        tree[j+1]=father;
        tree[j+2]=0;

        tree[j+3]=s[1];
        tree[j+4]=father;
        tree[j+5]=1;

        j=j+6;/*每次处理6个数据*/

        /*对s数组进行处理*/
        s[0]=father;
        s[1]=1000;/*1000在此是填补空位之用,
                       以后也作为循环跳出的判断条件*/
     }while(s[0]<1000);/*s[0]>1000时说明1000已经参与运算,需要停止*/
     tree[26]=2;/*最顶的哪个数字并不是左子树或者右子树,
                 所以它的这个属性设置为2,以区别。*/
/*******************************************************************/

    printf("====================================================\n");
    for(i=0;i<27;i++)
        {
        printf("%5d,",tree[i]);
        if((i+1)%3==0)
           printf("\n");
        }
/*******************************************************************/
    /*一下对tree进行处理,得到最优的01串*/
    for(i=0;i<3;i++)
        huf_code[i]=2;/*对huf_code所有元素赋值2,以区别
                       以后的01*/
    printf("====================================================\n");
    k=0;
    do
        {
        /*每三个一组分别是:本身,父亲,左(0,右(1)*/
        huf_code[0]=tree[k+2];
        for(i=0;i<27;i=i+3)
           if(tree[k+1]==tree[i])
              {
                 huf_code[1]=tree[i+2];
                 break;
               }
        for(j=i;j<27;j=j+3)
            if(tree[j]==tree[i+1])
               huf_code[2]=tree[j+2];

        for(ii=0;ii<5;ii++)
           if(tree[k]==s1[ii])
           {
              printf("\n  %5d:",s1[ii]);
              for(jj=2;jj>=0;jj--)
                 {
                 if(huf_code[jj]==2)continue;/*跳出本次循环,继续进行
                                               下一次循环。*/
                 printf("%5d,",huf_code[jj]);
                 }
           }
        k=k+3;
        }while(k<27);
    getch();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值