哈夫曼编码

来源:互联网 发布:广联达软件专用电脑 编辑:程序博客网 时间:2024/06/06 16:26
#include<iostream.h>const int MAX=20;//哈夫曼树输入数据的结构struct huffinit{    char data;    int weight;};//哈夫曼树结点的结构struct huffnode{    int weight;    int lchild,rchild,parent;};//哈夫曼树编码的结构struct huffcode{    char data;    char code[MAX+1];};huffnode tree[2*MAX-1]; //存huffman树huffcode cd[MAX];  //存编码信息int size; //叶子结点个数void Select(int &min1,int &min2,int m){    min1=min2=0;    int m1=32767,m2;    int i,t;    for(i=0;i<m;i++)    {        if(tree[i].parent==-1)            if(tree[i].weight<m1)            {                m2=m1;                min2=min1;                m1=tree[i].weight;                min1=i;            }            else if(tree[i].weight<m2)            {                m2=tree[i].weight;                min2=i;            }    }    if(min1>min2)    {        t=min1;        min1=min2;        min2=t;    }}void HuffTree(huffinit w[],int n){    int i;    for(i=0;i<2*n-1;i++)//初始化,所有的结点均没有双亲和孩子    {        tree[i].parent=-1;        tree[i].lchild=-1;        tree[i].rchild=-1;    }    for(i=0;i<n;i++)//构造出n颗只含有根节点的二叉树    {        cd[i].data=w[i].data;//结点值        tree[i].weight=w[i].weight;//权值    }    int k,i1,i2;    for(k=n;k<2*n-1;k++)//经过n-1次合并    {        Select(i1,i2,k);//查找出最小的两个根节点,下标为i1,i2        tree[i1].parent=k;//将i1和i2合并,且i1和i2的双亲为k        tree[i2].parent=k;        tree[k].weight=tree[i1].weight+tree[i2].weight;        tree[k].lchild=i1;        tree[k].rchild=i2;    }    size=n;}void Output()//输出哈夫曼树各节点的信息{    int i;    cout<<"已建好的哈夫曼树各结点信息为:"<<endl;    for(i=0;i<2*size-1;i++)        cout<<tree[i].weight<<" "<<tree[i].parent<<" "<<tree[i].lchild<<" "<<tree[i].rchild<<endl;}void Encode()//对结点进行编码{    int i;    for(i=0;i<size;i++)    {        char code[MAX+1];        int start=MAX+1;        int parent=tree[i].parent;        int position=i;        while(parent!=-1)        {            start--;            if(tree[parent].lchild==position)code[start]='0';            elsecode[start]='1';            position=parent;            parent=tree[parent].parent;        }        int j=0;        while(start<=MAX)        {            cd[i].code[j]=code[start];            j++;            start++;        }        cd[i].code[j]='\0';    }}void OutCode()//输出哈夫曼树的各节点编码{    int i;    cout<<"已建好的哈夫曼树各结点编码为:"<<endl;    for(i=0;i<size;i++)        cout<<cd[i].data<<"--->"<<cd[i].code<<endl;}void Decode(char code[])//解码操作{    int i=0;    int j=2*(size-1); //从根开始    char dec[MAX]; //暂存已解出的字符    int k=0;    while(code[i]!='\0')    {        if(code[i]=='0')            j=tree[j].lchild;        else            j=tree[j].rchild;        if(tree[j].lchild==-1)        {            dec[k++]=cd[j].data;            j=2*(size-1);        }        i++;    }    dec[k]='\0';    //密码串读完时,若没同时达到叶子(未重新回到根),则密码串有误    if(j!=2*(size-1)&&tree[j].lchild!=-1)        cout<<"此密码串无解!";    else        cout<<dec;    cout<<endl;}void main(){    huffinit info[MAX];    int i,n;    cin>>n;    for(i=0;i<n;i++)    {        cin>>info[i].data;        cin>>info[i].weight;    }    HuffTree(info,n);    Output();//节点信息    cout<<endl;    Encode();//进行编码    OutCode();//已建好的哈夫曼树的结点编码信息    cout<<endl;    char flag='Y';    do{        cout<<"请输入密码:";        char code[30];        cin>>code;        cout<<"解码结果为:";        Decode(code);//进行解码        cout<<endl;        cout<<"还继续解码吗?(Y/N)";        cin>>flag;    }while(flag=='Y'||flag=='y');}

原创粉丝点击