Huffman

Description
1、问题描述
给定n个字符及其对应的权值,构造Huffman树,并进行huffman编码和译(解)码。
构造Huffman树时,要求左子树根的权值小于右子树根的权值。
进行Huffman编码时,假定Huffman树的左分支上编码为‘0’,右分支上编码为‘1’。


2、算法
 构造Huffman树算法:
⑴、根据给定的n个权值(w1, w2, …, wn)构成n棵二叉树的集合F={T1, T2, …, Tn},其中每棵二叉树Ti中只有一个权值为wi的根结点
⑵、在F中选取两棵根结点的权值最小的树,作为左、右子树构造一棵新的二叉树,且置其根结点的权值为其左、右子树权值之和
⑶、在F中删除这两棵树,同时将新得到的二叉树加入F中
⑷、重复⑵, ⑶,直到F只含一棵树为止


Huffman编码算法:
⑴、从Huffman树的每一个叶子结点开始
⑵、依次沿结点到根的路径,判断该结点是父亲结点的左孩子还是右孩子,如果是左孩子则得到编码‘0’,否则得到编码‘1’,先得到的编码放在后面
⑶、直到到达根结点,编码序列即为该叶子结点对应的Huffman编码


Huffman译(解)码算法:
⑴、指针指向Huffman树的根结点,取第一个Huffman码
⑵、如果Huffman码为‘0’,将指针指向当前结点的左子树的根结点;如果Huffman码为‘1’,将指针指向当前结点的右子树的根结点
⑶、如果指针指向的当前结点为叶子结点,则输出叶子结点对应的字符;否则,取下一个Huffman码,并返回⑵
⑷、如果Huffman码序列未结束,则返回⑴继续译码


Input
第一行:样本字符个数,假设为n。
第二行,n个字符(用空格隔开)
第三行,n个字符对应的权值(用空格隔开)
第四行,待编码的字符串
第五行,待译码的Huffman码序列


Output
第一行,每个字符对应的Huffman编码(用空格隔开)
第二行,字符串对应的Huffman编码序列
第三行,Huffman码序列对应的字符串


Sample Input
4
a b c d
9 3 2 6
abcd
111001010
Sample Output
0 101 100 11
010110011
dcba
#include <iostream>  
#include <string.h>  
using namespace std;  
#define MAXCODELEN 15  
#define MAXHUFFMANCODENO 10  
#define MAXCODESTRINGLEN 100  
typedef struct 
{  
    char c;  
    int weight;  
    int parent,lchild,rchild;  
    char code[MAXCODELEN];  
}  
  
HTNode,*HuffmanTree;  
HTNode HT[2*MAXHUFFMANCODENO];  
  
void Select(int i1,int *s1,int *s2)  
{  
    unsigned int j,s;  
    s=0;  
    for (j=1;j<=i1;j++)  
    {  
        if (HT[j].parent==0)  
        {  
            if(s==0)  
            s=j;  
            if(HT[j].weight<HT[s].weight)  
                s=j;  
        }  
    }  
    *s1=s;  
    s=0;  
    for (j=1;j<=i1;j++)  
    {  
        if((HT[j].parent==0) && (j!=*s1))  
        {  
            if(s==0)  
                s=j;  
            if (HT[j].weight<HT[s].weight)  
                s=j;  
        }  
    }  
    *s2=s;  
}  
void CreateHuffmanTree(int n,char *c,int *w)  
{  
    int i,m,s1,s2;  
    m=2*n-1;  
    for(i=1;i<=n;++i)  
    {  
        HT[i].c=c[i-1];  
        HT[i].weight=w[i-1];  
        HT[i].parent=0;  
        HT[i].lchild=HT[i].rchild=0;  
    }  
    for ( ;i<=m;++i)  
    {  
        HT[i].weight=0;  
        HT[i].parent=HT[i].lchild=HT[i].rchild=0;  
    }  
    for (i=n+1;i<=m;++i)  
    {  
        Select(i-1,&s1,&s2);  
        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;  
    }  
}  
void HuffmanCoding(int n)  
{  
    int i,j,m,c,f,start;  
    char cd[MAXCODELEN];  
    m=MAXCODELEN;  
    cd[m-1]=0;  
    for(i=1;i<=n;i++)  
    {  
        start=m-1;  
        for(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';  
        }  
        for (j=0;j<m-start;j++)  
            HT[i].code[j]=cd[start+j];  
        HT[i].code[j]=0;  
    }  
}  
void ShowHuffmanCode(int n)  
{  
    int i;  
    for(i=1;i<n;i++)  
    cout<<HT[i].code<<" ";  
    cout<<HT[i].code<<endl;  
}  
int ShowHuffmanEncode(int n,char *eString)  
{  
    int i,j;  
    for (j=0;j<strlen(eString);j++)  
    {  
        for(i=1;i<=n;i++)  
        {  
            if(eString[j]==HT[i].c)  
            {  
                cout<<HT[i].code;  
                break;  
            }  
        }  
        if(i>n)  
            return 0;  
    }  
    cout<<endl;  
    return 1;  
}  
int ShowHuffmanDecode(int n,char *dString)  
{  
    int i,c,Root;  
    Root=2*n-1;  
    c=Root;  
    for(i=0;i<strlen(dString);i++)  
    {  
        if((HT[c].lchild==0) && (HT[c].rchild==0))  
        {  
            cout<<HT[c].c;  
            c=Root;  
        }  
        if(dString[i]=='0')  
        {  
            if (HT[c].lchild==0)  
                return 0;  
            c=HT[c].lchild;  
        }  
        else
        {  
            if(HT[c].rchild==0)  
                return 0;  
            c=HT[c].rchild;  
        }  
    }  
    cout<<HT[c].c<<endl;  
    return 1;  
}  
int main(int argc,char *argv[])  
{  
    int i,SampleNo,weight[MAXHUFFMANCODENO];  
    char c[MAXHUFFMANCODENO],EncodeString[MAXCODESTRINGLEN],DecodeString[MAXCODESTRINGLEN];  
    cin>>SampleNo;  
    for(i=0;i<SampleNo;i++)  
        cin>>c[i];  
    for(i=0;i<SampleNo;i++)  
        cin>>weight[i];  
    CreateHuffmanTree(SampleNo,c,weight);  
    HuffmanCoding(SampleNo);  
    ShowHuffmanCode(SampleNo);  
    cin>>EncodeString;  
    ShowHuffmanEncode(SampleNo,EncodeString);  
    cin>>DecodeString;  
    ShowHuffmanDecode(SampleNo,DecodeString);  
    return 0;  
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值