赫夫曼编码

 

#include<iostream>
#include<string>
using namespace std;
typedef struct
{
      unsigned int weight;                //权
      unsigned int parent,lchild,rchild;    //父,左子,右子节点
}HTNode,*HuffmanTree;                    //动态分配数组存储赫夫曼树   
typedef char** HuffmanCode;                //动态分配数组存储赫夫曼编码
//-----------------赫夫曼编码的算法实现-------------//
void SetHuffmanTree(HuffmanTree &HT,int weight, int parent, int lchild, int rchild)
{
   HT->weight=weight; 
   HT->parent = parent;
   HT->lchild = lchild;
   HT->rchild = rchild;
}
void Select(HuffmanTree HT,int n, int &s1, int &s2)
{
    //在HT[1...n]选择parent为0且weight最小的两个节点,分别赋给s1,s2
    //s1最小,s2次小
    int min=0,mun=0;
      HT[0].weight = 30000;
    for(int i=1;i<=n;i++)
 { 
        if(HT[i].parent==0)
  {  
            if(HT[i].weight<HT[min].weight)
   {   
                 mun = min;
                 min=i;
   }
           else if(HT[i].weight<HT[mun].weight)
             mun=i;
         }       
      }
      s1=min;   
      s2= mun;
}
void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n)
{
    //w存放n个字符的劝值(均>0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码
    if(n<=1)
  return;
    int m= 2*n-1;            //m:总共节点数
    HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));    //0号单元未用
    if(!HT)
  return;       
    int i;
      HuffmanTree p;
    for( p=HT+1,i=1; i<=n; i++,p++,w++)   
      SetHuffmanTree(p,*w,0,0,0);  //HT叶子的初值
    for(;i<=m;i++,p++) 
      SetHuffmanTree(p,0,0,0,0);                     //HT非叶子节点的初值
    for(i=n+1;i<=m; i++)
 {    //建赫夫曼树
           int s1,s2;
          Select(HT,i-1,s1,s2);    //找出weight值最小的两个节点
          HT[s1].parent=i;
          HT[s2].parent=i;
          HT[i].lchild=s1;
          HT[i].rchild=s2;
          HT[i].weight=HT[s1].weight + HT[s2].weight;
      }
    //-----------从叶子到根逆向求每个字符的赫夫曼编码 ------//
      HC= (HuffmanCode) malloc( (n+1)*sizeof(char *) );        //分配n个字符编码的头指针向量
      char *cd =(char *)malloc(n*sizeof(char));
      cd[n-1]=' ';
    for(i=1;i<=n;i++)
 {
        int start=n-1;
        for(int 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]);
    puts(HC[i]);//输出编码
      }

      free(cd);
}
int main()
{
  HuffmanTree A;
  HuffmanCode B;
  int n=4;
  int w[4];
  int i;
  for(i=0;i<4;i++)
   cin>>w[i];
 
  B=(HuffmanCode) malloc( (n+1)*sizeof(char *) );
  HuffmanCoding(A,B,w,n);
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值