Huffman Code 编码译码

来源:互联网 发布:根据ip查询域名 编辑:程序博客网 时间:2024/05/22 15:09

赫夫曼编码在通讯中应用广泛,赫夫曼树的建树实际上是一个贪心过程,根据所给的字符权值,优先选取权值小的建树,这样子到最后就可以缩短电文的长度。

e.g.

如果有A~H八个字符编码,如下图:
这里写图片描述

实现如下:

#include <algorithm>#include <bitset>#include <cassert>#include <climits>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <deque>#include <iomanip>#include <iostream>#include <map>#include <numeric>#include <queue>#include <set>#include <stack> #include <string>#define INF 0x3f3f3f3fusing namespace std;int s1,s2;int m;char str[10]={'$','A','B','C','D','E','F','G','H'};typedef struct {    char ch;    int data;    int p,lc,rc;}Htree,*Hufftree;typedef char* Huffcode;void select (Hufftree &Ht,int n){    //char *cd;    int min1,min2;    min1=min2=INF;//找最小权值    s1=s2=0;//纪录最小权值的位置    int i;    for (i=1;i<=n;i++)    {        if (!Ht[i].p)            if (Ht[i].data<min1)            {                min2=min1;                s2=s1;                min1=Ht[i].data;                s1=i;            }            else if (Ht[i].data<min2)            {                s2=i;                min2=Ht[i].data;            }    }}void Huffman(Hufftree &Ht,Huffcode Hc[],int *w,int n)    {    int start;    char *cd;    int i,c,f;    if (n<1)        return;    m=2*n-1;//静态链表总长度    Ht=(Htree*)malloc ((m+1)*sizeof(Htree));    for (i=1;i<=n;i++)    {        Ht[i].ch=str[i];        Ht[i].data=w[i-1];        Ht[i].p=0;        Ht[i].lc=-1;        Ht[i].rc=-1;    }//录入数据    for(i=n+1;i<=m;i++)    {        Ht[i].data=0;        Ht[i].lc=-1;        Ht[i].rc=-1;        Ht[i].p=0;    }//初始化    for (i=n+1;i<=m;i++)    {        select(Ht,i-1);        Ht[s1].p=i;        Ht[s2].p=i;        Ht[i].lc=s1;        Ht[i].rc=s2;        Ht[i].data=Ht[s1].data+Ht[s2].data;//更新节点权值    }//    cd=(char *)malloc (n*sizeof(char));    start=0;    cd[n-1]='\0';    for (i=1;i<=n;i++)    {        start=n-1;        for(c=i,f=Ht[i].p;f!=0;c=f,f=Ht[f].p)        {            if (Ht[f].lc==c)                cd[--start]='0';            else                cd[--start]='1';        }        Hc[i]=(char*)malloc((n-start)*sizeof(char));        strcpy (Hc[i],&cd[start]);    }}void decode(Hufftree &Ht){    int i,j=0;    i=m;    char b[20];    printf("输入编码(End #):\n");    scanf("%s",b);    printf("Results:\n");    while(b[j]!='#')    {        //printf("%c ",b[j]);        if(b[j]=='0')            i=Ht[i].lc;        else            i=Ht[i].rc;        if(Ht[i].lc==-1)        {            printf("%c",Ht[i].ch);            i=m;   //每次译码从头开始        }        j++;    }    printf("\n");}int main (){    Hufftree Ht;    Huffcode *Hc;    int w[20];    int i,n;    cout<<"Coding"<<endl;    printf("编码字符个数:\n");    scanf("%d",&n);    Hc=(Huffcode*)malloc(n*sizeof(Huffcode));    printf("编码的字符的频率:\n");    for (i=0;i<n;i++)        scanf("%d",&w[i]);    Huffman(Ht,Hc,w,n);    printf("字符编码为:\n");    cout<<"字符  权值  编码"<<endl;    for (i=1;i<=n;i++)    {        printf ("%c    %d     %s\n",str[i],w[i-1],Hc[i]);    }    cout<<"Decoding"<<endl;    decode(Ht);    return 0;}  
0 0
原创粉丝点击