赫夫曼编码

已知某系统在通信联络中只可能出现8种字符,其概率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,试编写算法求其赫夫曼编码

1 #include<iostream>
2 using namespace std;
3 //#include "HTNode.h"
4 typedef char **HuffmanCode;
5 typedef struct
6 {
7     int weight;
8     int parent,lchild,rchild;
9 }HTNode,*HuffmanTree;
void Select(HuffmanTree &HT,int n,int &s1,int &s2)
{
    int i;
    int min=0;
    for(i=1;i<=n;++i)
    {
        if(HT[i].parent==0)
        {
            if(min==0)
            {
                min=HT[i].weight;min++;s1=i;
            }            
            if(HT[i].weight<min)
            {
                min=HT[i].weight;s1=i;
            }
        }
    }


    min=0;
    for(i=1;i<=n;++i)
    {
        if((HT[i].parent==0)&&(i!=s1))
        {
            if(min==0)
            {min=HT[i].weight;min++;s2=i;}
            if(HT[i].weight<min)
            {min=HT[i].weight;s2=i;}
        }
    }
    if(s2<s1) //保证s1的下标值小与s2实现左右子树的大小对称
    {
        s1=s1+s2;
        s2=s1-s2;
        s1=s1-s2;
    } 
}


void CreatHuffmanTree(HuffmanTree &HT,int n)
{ 
    //构造赫夫曼树
    int i,m,s1,s2;
    if(n<=1)return;
    m=2*n-1;
    HT=new HTNode[m+1];//树的信息储存在数组中
    for(i=1;i<=m;++i)
    {
        HT[i].parent=0;
        HT[i].lchild=0;
        HT[i].rchild=0;
    }
    cout<<"请输入8个权值:
";
    for(i=1;i<=n;++i)
    cin>>HT[i].weight;//输入树叶子结点的权值
    for(i=n+1;i<=m;++i)
    {
        //在HT数组中选择两个其双亲域为0且权值最小的结点,并返回它们的下标S1,S2
        Select(HT,i-1,s1,s2);

        cout<<"s1="<<s1<<"s2="<<s2<<endl;
        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 CreatHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)
{
    int start,i,c,f;
    HC=new char*[n+1];
    char *cd=new char[n];
    cd[n-1]='';
    for(i=1;i<=n;++i)
    {
        start=n-1;
        c=i;f=HT[i].parent;
        while(f!=0)
        {
            --start;
            if(HT[f].lchild==c) cd[start]='0';
            else cd[start]='1';
            c=f;f=HT[f].parent;
        }
        HC[i]=new char[n-start];
        strcpy(HC[i],&cd[start]);
    }
    delete cd;
}
int main()
{
    HuffmanTree HT;
    HuffmanCode HC;
    int i,n=8;
    CreatHuffmanTree(HT,n);
    CreatHuffmanCode(HT,HC,n);
    for(i=1;i<=n;i++)
        cout<<""<<i<<"个字符的编码"<<HC[i]<<endl;
    return 0;
}

/*
请输入8个权值:
5 29 7 8 14 23 3 11
s1=1 s2=7
s1=3 s2=4
s1=8 s2=9
s1=5 s2=10
s1=6 s2=11
s1=2 s2=12
s1=13 s2=14
第1个字符的编码0110
第2个字符的编码10
第3个字符的编码1110
第4个字符的编码1111
第5个字符的编码110
第6个字符的编码00
第7个字符的编码0111
第8个字符的编码010
Press any key to continue
*/

原文地址:https://www.cnblogs.com/Lijcyy/p/13836809.html