1. 程式人生 > >哈夫曼編碼--貪心策略

哈夫曼編碼--貪心策略

round 心算 ase value 刪除 huffman sin fine pac

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

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

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

步驟 :

  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;//?¨ò?μ?ê??úμ?·?±eóDè¨??£????×?úμ?£?×óóòo¢×ó£??1óD′ú±íμ?×?·? typedef struct{ int bit[MAXBIT]; int start; }HCodeType;//?aê?±à???á11ì? HNodeType HuffNode[MAXNODE];//
?úμ??á11ì?êy×é HCodeType HuffCode[MAXLEAF];//±à???á11ì?êy×é /*?ó??à′?aê?11?ì1t·ò?üê÷*/ void HuffmanTree(HNodeType HuffNode[MAXNODE],int n) { /*i,jê??-?·±?á?£?m1,m2ê?×?D?μ?è¨?μ x1,x2ê?1t·ò?üê÷×?D?è¨?μ??ó|μ?Dòo? */ int i,j,x1,x2; double m1,m2; // 3?ê??ˉ?úμ? 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; } // 11?ì1t?¥?üê÷ for(i=0;i<n-1;i++) {//òa?-?·n-1′? m1=m2=MAXVALUE; x1=x2=0; //?????aê??ò×?D?μ?á????μ 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;//ó?óú2aê? } } 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; }

哈夫曼編碼--貪心策略