哈夫曼編碼--貪心策略


哈夫曼編碼還是在暑假時候看的,那時候並沒有看懂因為比較菜(雖然現在也是很菜的),在《趣學算法》一書中這個問題講解十分到位,我這篇博客真的是難以望其項背,只能對其進行一點借鑒和摘抄吧

哈夫曼編碼是一棵樹,權值越大的節點越靠近樹根,越小的節點就越遠離樹根,從他的定義來看,首先想到的應該是貪心策略吧,沒錯就是貪心算法

雖然說是貪心算法,但是還要知道它 的實現方式啊,他的貪心策略是:每次從樹的集合中取出沒有雙親且權值最小的兩棵樹作為左右子樹,並合並他們

步驟 :

  1 :確定合適的數據結構(要知道他的左右子樹,雙親,權值)

  2:初始化,構造n顆節點為n的字符單節點樹集合T={t1,t2,t3,t4···········tn},並且每棵樹只有樹根

  3:如果集合中只剩下一棵樹,那么哈夫曼樹就構造成功,直接跳轉到步驟6,否則就是從集合中繼續拿出沒有雙親的左右子樹x,y,並將它們合並到一顆z樹中,

    z的權值為左右子樹權值之和

  4:從T集合中刪除x,y 把新樹z加入到集合T中

  5:重復步驟3~4

  6:約定左分支上的編碼都是0,有分支上的編碼都是1,從葉子節點開始逆序求出樹的編碼

圖解:(這兒就直接調用這本書上的圖片吧,是在太懶不想畫圖)

  

代碼的實現:

#include<bits/stdc++.h>
using namespace std;
#define MAXBIT 100
#define MAXVALUE 10000
#define MAXLEAF 30
#define MAXNODE MAXLEAF*2-1
typedef struct{
    double weight;
    int parent;
    int lchild;
    int rchild;
    char value;
}HNodeType;//¶¨ÒåµÄÊǽڵã·Ö±ðÓÐÈ¨ÖØ£¬Ë«Ç׽ڵ㣬×óÓÒº¢×Ó£¬»¹Óдú±íµÄ×Ö·û 
typedef struct{
    int bit[MAXBIT];
    int start;
}HCodeType;//ÕâÊDZàÂë½á¹¹Ìå 
HNodeType HuffNode[MAXNODE];//½Úµã½á¹¹ÌåÊý×é 
HCodeType HuffCode[MAXLEAF];//±àÂë½á¹¹ÌåÊý×é 
/*½ÓÏÂÀ´¿ªÊ¼¹¹Ôì¹þ·òÂüÊ÷*/
void HuffmanTree(HNodeType HuffNode[MAXNODE],int n)
{
    /*i,jÊÇÑ­»·±äÁ¿£¬m1,m2ÊÇ×îСµÄȨֵ
    x1,x2Êǹþ·òÂüÊ÷×îСȨֵ¶ÔÓ¦µÄÐòºÅ
    */
    int i,j,x1,x2;
    double m1,m2;
//    ³õʼ»¯½Úµã 
    for(i=0;i<2*n-1;i++)
    {
        HuffNode[i].lchild=-1;
        HuffNode[i].parent=-1;
        HuffNode[i].rchild=-1;
        HuffNode[i].weight=0;
    }
    for(i=0;i<n;i++)
    {
        cout<<"Please enter the value of every Node "<<i+1<<endl;
        cin>>HuffNode[i].value>>HuffNode[i].weight;
    }
//    ¹¹Ôì¹þ¸¥ÂüÊ÷
    for(i=0;i<n-1;i++)
    {//Ҫѭ»·n-1´Î 
        m1=m2=MAXVALUE;
        x1=x2=0;
    //ÏÂÃæ¿ªÊ¼ÕÒ×îСµÄÁ½¸öÖµ
        for(j=0;j<n+i;j++)
        {
            if(HuffNode[j].weight<m1&&HuffNode[j].parent==-1)
            {
                m2=m1;
                x2=x1;
                m1=HuffNode[j].weight;
                x1=j;
            }
            else if(HuffNode[j].weight<m2&&HuffNode[j].parent==-1)
            {
                m2=HuffNode[j].weight;
                x2=j;
            }
        }
        HuffNode[x1].parent=n+i;
        HuffNode[x2].parent=n+i;
        HuffNode[n+i].weight=m1+m2;
        HuffNode[n+i].lchild=x1;
        HuffNode[n+i].rchild=x2;
        cout<<"x1.weight and x2.weight in round "<<i+1<<"\t"
            <<HuffNode[x1].weight<<"\t"<<HuffNode[x2].weight<<endl;//ÓÃÓÚ²âÊÔ
         
    }
}
void HuffmanCode(HCodeType HuffCode[MAXLEAF],int n)
{
    HCodeType cd;
    int i,j,c,p;
    for(i=0;i<n;i++)
    {
        cd.start=n-1;
        c=i;
        p=HuffNode[c].parent;
        while(p!=-1)
        {
            if(HuffNode[p].lchild==c)
                cd.bit[cd.start]=0;
            else 
                cd.bit[cd.start]=1;
            cd.start--;
            c=p;
            p=HuffNode[c].parent;
        }
        for(j=cd.start+1;j<n;j++)
            HuffCode[i].bit[j]=cd.bit[j];
        HuffCode[i].start=cd.start;
    }
}
int main()
{
    int i,j,n;
    cout<<"Please enter n"<<endl;
    cin>>n;
    HuffmanTree(HuffNode,n);
    HuffmanCode(HuffCode,n);
    for(i=0;i<n;i++)
    {
        cout<<HuffNode[i].value<<": Huffman Code is: ";
        for(j=HuffCode[i].start+1;j<n;j++)
        {
            cout<<HuffCode[i].bit[j];
        }
        cout<<endl;
    }
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM