0023算法筆記——【貪心算法】哈夫曼編碼問(wèn)題參考模板_第1頁(yè)
0023算法筆記——【貪心算法】哈夫曼編碼問(wèn)題參考模板_第2頁(yè)
0023算法筆記——【貪心算法】哈夫曼編碼問(wèn)題參考模板_第3頁(yè)
0023算法筆記——【貪心算法】哈夫曼編碼問(wèn)題參考模板_第4頁(yè)
0023算法筆記——【貪心算法】哈夫曼編碼問(wèn)題參考模板_第5頁(yè)
已閱讀5頁(yè),還剩11頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、0023算法筆記【貪心算法】哈夫曼編碼問(wèn)題   1、問(wèn)題描述      哈夫曼編碼是廣泛地用于數(shù)據(jù)文件壓縮的十分有效的編碼方法。其壓縮率通常在20%90%之間。哈夫曼編碼算法用字符在文件中出現(xiàn)的頻率表來(lái)建立一個(gè)用0,1串表示各字符的最優(yōu)表示方式。一個(gè)包含100,000個(gè)字符的文件,各字符出現(xiàn)頻率不同,如下表所示。    有多種方式表示文件中的信息,若用0,1碼表示字符的方法,即每個(gè)字符用唯一的一個(gè)0,1串表示。若采用定長(zhǎng)編碼表示,則需要3位表示一個(gè)字符,整個(gè)文件編碼需要300,000位;若采用變長(zhǎng)編碼表示

2、,給頻率高的字符較短的編碼;頻率低的字符較長(zhǎng)的編碼,達(dá)到整體編碼減少的目的,則整個(gè)文件編碼需要(45×1+13×3+12×3+16×3+9×4+5×4)×1000=224,000位,由此可見(jiàn),變長(zhǎng)碼比定長(zhǎng)碼方案好,總碼長(zhǎng)減小約25%。     前綴碼:對(duì)每一個(gè)字符規(guī)定一個(gè)0,1串作為其代碼,并要求任一字符的代碼都不是其他字符代碼的前綴。這種編碼稱為前綴碼。編碼的前綴性質(zhì)可以使譯碼方法非常簡(jiǎn)單;例如001011101可以唯一的分解為0,0,101,1101,因而其譯碼為aabe。1 / 16

3、60;    譯碼過(guò)程需要方便的取出編碼的前綴,因此需要表示前綴碼的合適的數(shù)據(jù)結(jié)構(gòu)。為此,可以用二叉樹(shù)作為前綴碼的數(shù)據(jù)結(jié)構(gòu):樹(shù)葉表示給定字符;從樹(shù)根到樹(shù)葉的路徑當(dāng)作該字符的前綴碼;代碼中每一位的0或1分別作為指示某節(jié)點(diǎn)到左兒子或右兒子的“路標(biāo)”。     從上圖可以看出,表示最優(yōu)前綴碼的二叉樹(shù)總是一棵完全二叉樹(shù),即樹(shù)中任意節(jié)點(diǎn)都有2個(gè)兒子。圖a表示定長(zhǎng)編碼方案不是最優(yōu)的,其編碼的二叉樹(shù)不是一棵完全二叉樹(shù)。在一般情況下,若C是編碼字符集,表示其最優(yōu)前綴碼的二叉樹(shù)中恰有|C|個(gè)葉子。每個(gè)葉子對(duì)應(yīng)于字符集中的一個(gè)字符,該二叉樹(shù)有|C|-1個(gè)內(nèi)部節(jié)點(diǎn)。

4、     給定編碼字符集C及頻率分布f,即C中任一字符c以頻率f(c)在數(shù)據(jù)文件中出現(xiàn)。C的一個(gè)前綴碼編碼方案對(duì)應(yīng)于一棵二叉樹(shù)T。字符c在樹(shù)T中的深度記為dT(c)。dT(c)也是字符c的前綴碼長(zhǎng)。則平均碼長(zhǎng)定義為:使平均碼長(zhǎng)達(dá)到最小的前綴碼編碼方案稱為C的最優(yōu)前綴碼。          2、構(gòu)造哈弗曼編碼     哈夫曼提出構(gòu)造最優(yōu)前綴碼的貪心算法,由此產(chǎn)生的編碼方案稱為哈夫曼編碼。其構(gòu)造步驟如下:     (1)哈夫曼算法以自底向上

5、的方式構(gòu)造表示最優(yōu)前綴碼的二叉樹(shù)T。     (2)算法以|C|個(gè)葉結(jié)點(diǎn)開(kāi)始,執(zhí)行|C|1次的“合并”運(yùn)算后產(chǎn)生最終所要求的樹(shù)T。     (3)假設(shè)編碼字符集中每一字符c的頻率是f(c)。以f為鍵值的優(yōu)先隊(duì)列Q用在貪心選擇時(shí)有效地確定算法當(dāng)前要合并的2棵具有最小頻率的樹(shù)。一旦2棵具有最小頻率的樹(shù)合并后,產(chǎn)生一棵新的樹(shù),其頻率為合并的2棵樹(shù)的頻率之和,并將新樹(shù)插入優(yōu)先隊(duì)列Q。經(jīng)過(guò)n1次的合并后,優(yōu)先隊(duì)列中只剩下一棵樹(shù),即所要求的樹(shù)T。      構(gòu)造過(guò)程如圖所示:     具

6、體代碼實(shí)現(xiàn)如下:     (1)4d4.cpp,程序主文件cpp view plain copy1. /4d4 貪心算法 哈夫曼算法  2. #include "stdafx.h"  3. #include "BinaryTree.h"  4. #include "MinHeap.h"  5. #include <iostream>&#

7、160;  6. using namespace std;   7.   8. const int N = 6;  9.   10. template<class Type> class Huffman;  11.   12. template<class Type>   13. BinaryT

8、ree<int> HuffmanTree(Type f,int n);  14.   15. template<class Type>   16. class Huffman  17.   18.     friend BinaryTree<int> HuffmanTree(Type,int);  19.  &#

9、160;  public:  20.         operator Type() const   21.           22.             return weight; 

10、; 23.           24.     /private:  25.         BinaryTree<int> tree;  26.         Type weight;  27.

11、 ;  28.   29. int main()  30.   31.     char c = '0','a','b','c','d','e','f'  32.     int f = 0,45,13,12,16,9,5;/下標(biāo)從1開(kāi)始

12、  33.     BinaryTree<int> t = HuffmanTree(f,N);  34.   35.     cout<<"各字符出現(xiàn)的對(duì)應(yīng)頻率分別為:"<<endl;  36.     for(int i=1; i<=N; i+)  37.

13、       38.         cout<<ci<<":"<<fi<<" "  39.       40.     cout<<endl;  41.   42.   

14、;  cout<<"生成二叉樹(shù)的前序遍歷結(jié)果為:"<<endl;  43.     t.Pre_Order();  44.     cout<<endl;  45.   46.     cout<<"生成二叉樹(shù)的中序遍歷結(jié)果為:"<<endl;  47. &#

15、160;   t.In_Order();  48.     cout<<endl;  49.   50.     t.DestroyTree();  51.     return 0;  52.   53.   54. template<class Type>

16、60; 55. BinaryTree<int> HuffmanTree(Type f,int n)  56.   57.     /生成單節(jié)點(diǎn)樹(shù)  58.     Huffman<Type> *w = new Huffman<Type>n+1;  59.     BinaryTree

17、<int> z,zero;  60.   61.     for(int i=1; i<=n; i+)  62.       63.         z.MakeTree(i,zero,zero);  64.       

18、  wi.weight = fi;  65.         wi.tree = z;  66.       67.   68.     /建優(yōu)先隊(duì)列  69.     MinHeap<Huffman<Type>>&

19、#160;Q(n);  70.     for(int i=1; i<=n; i+) Q.Insert(wi);  71.   72.     /反復(fù)合并最小頻率樹(shù)  73.     Huffman<Type> x,y;  74.     for(int i=1

20、; i<n; i+)  75.       76.         x = Q.RemoveMin();  77.         y = Q.RemoveMin();  78.       &

21、#160; z.MakeTree(0,x.tree,y.tree);  79.         x.weight += y.weight;  80.         x.tree = z;  81.         Q.Insert(x); 

22、; 82.       83.   84.     x = Q.RemoveMin();  85.   86.     delete w;  87.   88.     return x.tree;  89.     &

23、#160;  (2)BinaryTree.h 二叉樹(shù)實(shí)現(xiàn)cpp view plain copy1. #include<iostream>  2. using namespace std;  3.   4. template<class T>  5. struct BTNode  6.   7.     T data; 

24、60;8.     BTNode<T> *lChild,*rChild;  9.   10.     BTNode()  11.       12.         lChild=rChild=NULL;  13.      &

25、#160;14.   15.     BTNode(const T &val,BTNode<T> *Childl=NULL,BTNode<T> *Childr=NULL)  16.       17.         data=val;  18.    &#

26、160;    lChild=Childl;  19.         rChild=Childr;  20.       21.   22.     BTNode<T>* CopyTree()  23.       

27、24.         BTNode<T> *nl,*nr,*nn;  25.   26.         if(&data=NULL)  27.         return NULL;  28.   29. 

28、0;       nl=lChild->CopyTree();  30.         nr=rChild->CopyTree();  31.   32.         nn=new BTNode<T>(data,nl,nr);  33.  

29、       return nn;  34.       35. ;  36.   37.   38. template<class T>  39. class BinaryTree  40.   41.     public: 

30、0;42.         BTNode<T> *root;  43.         BinaryTree();  44.         BinaryTree();  45.   46.      

31、60;  void Pre_Order();  47.         void In_Order();  48.         void Post_Order();  49.   50.         int Tr

32、eeHeight()const;  51.         int TreeNodeCount()const;  52.   53.         void DestroyTree();  54.         void MakeTree(T&#

33、160;pData,BinaryTree<T> leftTree,BinaryTree<T> rightTree);  55.         void Change(BTNode<T> *r);  56.   57.     private:  58.      

34、0;  void Destroy(BTNode<T> *&r);  59.         void PreOrder(BTNode<T> *r);  60.         void InOrder(BTNode<T> *r);  61.  &

35、#160;      void PostOrder(BTNode<T> *r);  62.   63.         int Height(const BTNode<T> *r)const;  64.         int Node

36、Count(const BTNode<T> *r)const;  65. ;  66.   67. template<class T>  68. BinaryTree<T>:BinaryTree()  69.   70.     root=NULL;  71.   72.   73. template<cl

37、ass T>  74. BinaryTree<T>:BinaryTree()  75.   76.       77.   78.   79. template<class T>  80. void BinaryTree<T>:Pre_Order()  81.   82.    

38、; PreOrder(root);  83.   84.   85. template<class T>  86. void BinaryTree<T>:In_Order()  87.   88.     InOrder(root);  89.   90.   91. template<class T>

39、  92. void BinaryTree<T>:Post_Order()  93.   94.     PostOrder(root);  95.   96.   97. template<class T>  98. int BinaryTree<T>:TreeHeight()const  99.   100.

40、     return Height(root);  101.   102.   103. template<class T>  104. int BinaryTree<T>:TreeNodeCount()const  105.   106.     return NodeCount(root);  107. &#

41、160; 108.   109. template<class T>  110. void BinaryTree<T>:DestroyTree()  111.   112.     Destroy(root);  113.   114.   115. template<class T>  116. void Bi

42、naryTree<T>:PreOrder(BTNode<T> *r)  117.   118.     if(r!=NULL)  119.       120.         cout<<r->data<<' '  121.   

43、;      PreOrder(r->lChild);  122.         PreOrder(r->rChild);  123.       124.   125.   126. template<class T>  127. void Binar

44、yTree<T>:InOrder(BTNode<T> *r)  128.   129.     if(r!=NULL)  130.       131.         InOrder(r->lChild);  132.       

45、60; cout<<r->data<<' '  133.         InOrder(r->rChild);  134.       135.   136.   137. template<class T>  138. void BinaryTree&

46、lt;T>:PostOrder(BTNode<T> *r)  139.   140.     if(r!=NULL)  141.       142.         PostOrder(r->lChild);  143.        

47、; PostOrder(r->rChild);  144.         cout<<r->data<<' '  145.       146.   147.   148. template<class T>  149. int BinaryTree&l

48、t;T>:NodeCount(const BTNode<T> *r)const  150.   151.     if(r=NULL)  152.         return 0;  153.     else  154.      

49、60;  return 1+NodeCount(r->lChild)+NodeCount(r->rChild);  155.   156.   157. template<class T>  158. int BinaryTree<T>:Height(const BTNode<T> *r)const  159.   160.    

50、; if(r=NULL)  161.         return 0;  162.     else  163.       164.         int lh,rh;  165.    

51、60;    lh=Height(r->lChild);  166.         rh=Height(r->rChild);  167.         return 1+(lh>rh?lh:rh);  168.       169.  

52、 170.   171. template<class T>  172. void BinaryTree<T>:Destroy(BTNode<T> *&r)  173.   174.     if(r!=NULL)  175.       176.      

53、60;  Destroy(r->lChild);  177.         Destroy(r->rChild);  178.         delete r;  179.         r=NULL;  180.  &#

54、160;    181.   182.   183. template<class T>  184. void BinaryTree<T>:Change(BTNode<T> *r)/將二叉樹(shù)bt所有結(jié)點(diǎn)的左右子樹(shù)交換  185.   186.     BTNode<T> *p;  187.  

55、0;  if(r)   188.         p=r->lChild;  189.         r->lChild=r->rChild;  190.         r->rChild=p; /左右子女交換  

56、;191.         Change(r->lChild);  /交換左子樹(shù)上所有結(jié)點(diǎn)的左右子樹(shù)  192.         Change(r->rChild);  /交換右子樹(shù)上所有結(jié)點(diǎn)的左右子樹(shù)  193.       194.   195.  &#

57、160;196. template<class T>  197. void BinaryTree<T>:MakeTree(T pData,BinaryTree<T> leftTree,BinaryTree<T> rightTree)  198.   199.     root = new BTNode<T>();  200.  

58、   root->data = pData;  201.     root->lChild = leftTree.root;  202.     root->rChild = rightTree.root;  203.        (3)MinHeap.h 最小堆實(shí)現(xiàn)cpp view pl

59、ain copy1. #include <iostream>  2. using namespace std;  3. template<class T>  4. class MinHeap  5.   6.     private:  7.         T *

60、heap; /元素?cái)?shù)組,0號(hào)位置也儲(chǔ)存元素  8.         int CurrentSize; /目前元素個(gè)數(shù)  9.         int MaxSize; /可容納的最多元素個(gè)數(shù)  10.   11.         

61、void FilterDown(const int start,const int end); /自上往下調(diào)整,使關(guān)鍵字小的節(jié)點(diǎn)在上  12.         void FilterUp(int start); /自下往上調(diào)整  13.   14.     public:  15.   &

62、#160;     MinHeap(int n=1000);  16.         MinHeap();  17.         bool Insert(const T &x); /插入元素  18.   19.   

63、0;     T RemoveMin(); /刪除最小元素  20.         T GetMin(); /取最小元素  21.   22.         bool IsEmpty() const;  23.    

64、;     bool IsFull() const;  24.         void Clear();  25. ;  26.   27. template<class T>  28. MinHeap<T>:MinHeap(int n)  29.   

65、30.     MaxSize=n;  31.     heap=new TMaxSize;  32.     CurrentSize=0;  33.   34.   35. template<class T>  36. MinHeap<T>:MinHeap()  37.   

66、;38.     delete heap;  39.   40.   41. template<class T>  42. void MinHeap<T>:FilterUp(int start) /自下往上調(diào)整  43.   44.     int j=start,i=(j-1)/2; /i指向j的雙親節(jié)

67、點(diǎn)  45.     T temp=heapj;  46.   47.     while(j>0)  48.       49.         if(heapi<=temp)  50.      

68、0;      break;  51.         else  52.           53.             heapj=heapi;  54.  &#

69、160;          j=i;  55.             i=(i-1)/2;  56.           57.       58.   &#

70、160; heapj=temp;  59.   60.   61. template<class T>  62. void MinHeap<T>:FilterDown(const int start,const int end) /自上往下調(diào)整,使關(guān)鍵字小的節(jié)點(diǎn)在上  63.   64.     int i=start,j=

71、2*i+1;  65.     T temp=heapi;  66.     while(j<=end)  67.       68.         if( (j<end) && (heapj>heapj+1) ) 

72、0;69.             j+;  70.         if(temp<=heapj)  71.             break;  72.     

73、60;   else  73.           74.             heapi=heapj;  75.             i=j;  76. 

74、60;           j=2*j+1;  77.           78.       79.     heapi=temp;  80.   81.   82. template<class T>  83. bool MinHeap<T>:Insert(const T &x)  84.   85.     if(CurrentSize=MaxSize)  

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論