当前位置: 代码迷 >> C语言 >> 求助一下 关于 哈夫曼编码译码器
  详细解决方案

求助一下 关于 哈夫曼编码译码器

热度:491   发布时间:2008-06-10 23:00:08.0
#include <iostream>
using namespace std;
#define N 20     /*待编码字符的个数,即树中叶结点的最大个数*/
#define M 2*N-1 /*树中总的结点数目*/

#include <iostream>
using namespace std;
#define N 20     /*待编码字符的个数,即树中叶结点的最大个数*/
#define M 2*N-1 /*树中总的结点数目*/

class Huffman{
    private:
        typedef struct{
            unsigned int weight;
            unsigned int parent,lchild,rchild;
        }HTNode;            //树的结构
        HTNode *HT;            
        
        typedef struct{
            char data;     //待编码的字符
            int weight;    //字符的权值
            char code[N]; //字符的编码
        }HTCode;           //编码表
        HTCode *HC;
        char *cd;          //需要的编码空间
        int n;
        
    public:
        Huffman();
        ~Huffman();
        void SetValue();   //设置字符数,和权值
        void Select(int k,int &s1,int &s2); //选择parent为0且weight最小的2个结点
        void HuffmanCoding();
};

Huffman::Huffman(){
    HT=new HTNode[N];
    HC=new HTCode[M];
    cd=new char[N];
    n=0;
}

Huffman::~Huffman(){
    delete []HT;
    delete []HC;
    delete []cd;
}

void Huffman::SetValue(){
    int i;
    cout<<"Input code number: "<<endl;
    cin>>n;
    cout<<"Input "<<n<<" charactor: "<<endl;
    for(i=0;i<n;++i)
        cin>>HC[i].data;
    cout<<"Input code weight:   "<<endl;
    for(i=0;i<n;++i)
        cin>>HC[i].weight;   
}

void Huffman::Select(int k,int &s1,int &s2){
    int i;
    for(i=0;i<k;++i)
    if(!HT[i].parent)
       s1=i;
    for(i=0;i<k;++i)
        if(!HT[i].parent&&HT[i].weight<HT[s1].weight)
           s1=i;
    for(i=0;i<k;++i)
        if(!HT[i].parent&&i!=s1)
           s2=i;
    for(i=0;i<k;++i)      
        if(!HT[i].parent&&HT[i].weight<HT[s2].weight&&i!=s1)
           s2=i;
}

void Huffman::HuffmanCoding(){
    //构造赫夫曼树HT,求出n个字符的赫夫曼编码HC
    int i,m=0,s1=0,s2=0;
    m=2*n-1;
    for(i=0;i<m;++i)               //初始化赫夫曼树
    {
        if(i<n)
        HT[i].weight=HC[i].weight;
        else
        HT[i].weight=0;
        HT[i].parent=HT[i].lchild=HT[i].rchild=0;
    }
    for(i=n;i<m;++i)           //构造赫夫曼树
    {
        Select(i,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;

    }
    cout<<"\nHuffmanTree: "<<endl;
    cout<<"weight\tparent\tlchild\trchild"<<endl;
    for(i=0;i<m;++i)
        cout<<HT[i].weight<<"\t"<<HT[i].parent
            <<"\t"<<HT[i].lchild<<"\t"<<HT[i].rchild<<endl;
    cout<<endl<<endl;
   
    cd[n-1]='\0';            
    int c=0,f=0,start=0;
    for(i=0;i<n;++i)              //逐个求赫夫曼编码
    {
        start=n-1;                //编码结束符下标
        for(c=i,f=HT[i].parent;f;c=f,f=HT[f].parent)//从叶子到根结点求编码
        if(HT[f].lchild==c)
           cd[--start]='1';//左分支1
           else
              cd[--start]='0'; //右分支0
        strcpy(HC[i].code,&cd[start]);
    }
   
    for(i=0;i<n;++i)           
        cout<<HC[i].data<<" --- "<<HC[i].code<<endl;
        
}
   
int main(){
    Huffman h;
    h.SetValue();
    h.HuffmanCoding();
   
    system("pause");
    return 0;
}
   

Huffman::Huffman(){
    HT=new HTNode[N];
    HC=new HTCode[M];
    cd=new char[N];
    n=0;
}

Huffman::~Huffman(){
    delete []HT;
    delete []HC;
    delete []cd;
}

void Huffman::SetValue(){
    int i;
    cout<<"Input code number: "<<endl;
    cin>>n;
    cout<<"Input "<<n<<" charactor: "<<endl;
    for(i=0;i<n;++i)
        cin>>HC[i].data;
    cout<<"Input code weight:   "<<endl;
    for(i=0;i<n;++i)
        cin>>HC[i].weight;   
}

void Huffman::Select(int k,int &s1,int &s2){
    int i;
    for(i=0;i<k;++i)
    if(!HT[i].parent)
       s1=i;
    for(i=0;i<k;++i)
        if(!HT[i].parent&&HT[i].weight<HT[s1].weight)
           s1=i;
    for(i=0;i<k;++i)
        if(!HT[i].parent&&i!=s1)
           s2=i;
    for(i=0;i<k;++i)      
        if(!HT[i].parent&&HT[i].weight<HT[s2].weight&&i!=s1)
           s2=i;
}

void Huffman::HuffmanCoding(){
    //构造赫夫曼树HT,求出n个字符的赫夫曼编码HC
    int i,m=0,s1=0,s2=0;
    m=2*n-1;
    for(i=0;i<m;++i)               //初始化赫夫曼树
    {
        if(i<n)
        HT[i].weight=HC[i].weight;
        else
        HT[i].weight=0;
        HT[i].parent=HT[i].lchild=HT[i].rchild=0;
    }
    for(i=n;i<m;++i)           //构造赫夫曼树
    {
        Select(i,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;

    }
    cout<<"\nHuffmanTree: "<<endl;
    cout<<"weight\tparent\tlchild\trchild"<<endl;
    for(i=0;i<m;++i)
        cout<<HT[i].weight<<"\t"<<HT[i].parent
            <<"\t"<<HT[i].lchild<<"\t"<<HT[i].rchild<<endl;
    cout<<endl<<endl;
   
    cd[n-1]='\0';            
    int c=0,f=0,start=0;
    for(i=0;i<n;++i)              //逐个求赫夫曼编码
    {
        start=n-1;                //编码结束符下标
        for(c=i,f=HT[i].parent;f;c=f,f=HT[f].parent)//从叶子到根结点求编码
        if(HT[f].lchild==c)
           cd[--start]='0';//左分支0
           else
              cd[--start]='1'; //右分支1
        strcpy(HC[i].code,&cd[start]);
    }
   
    for(i=0;i<n;++i)           
        cout<<HC[i].data<<" --- "<<HC[i].code<<endl;
        
}
   
int main(){
    Huffman h;
    h.SetValue();
    h.HuffmanCoding();
   
    system("pause");
    return 0;
}

[[it] 本帖最后由 无聊人士 于 2008-6-10 23:01 编辑 [/it]]
----------------解决方案--------------------------------------------------------
偶以前写的,码有点糙.. 希望对你有帮助!
----------------解决方案--------------------------------------------------------
楼上要是早点给出啦。。我就不写了。。呵呵。。
----------------解决方案--------------------------------------------------------
  相关解决方案