版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、.0023算法筆記【貪心算法】哈夫曼編碼問題1、問題描述 哈夫曼編碼是廣泛地用于數(shù)據(jù)文件壓縮的十分有效的編碼方法。其壓縮率通常在20%90%之間。哈夫曼編碼算法用字符在文件中出現(xiàn)的頻率表來建立一個用0,1串表示各字符的最優(yōu)表示方式。一個包含100,000個字符的文件,各字符出現(xiàn)頻率不同,如下表所示。 有多種方式表示文件中的信息,若用0,1碼表示字符的方法,即每個字符用唯一的一個0,1串表示。若采用定長編碼表示,則需要3位表示一個字符,整個文件編碼需要300,000位;若采用變長編碼表示,給頻率高的字符較短的編碼;頻率低的字符較長的編碼,達(dá)到整體編碼減少的目的,則整個文件編碼需要(451+133
2、+123+163+94+54)1000=224,000位,由此可見,變長碼比定長碼方案好,總碼長減小約25%。 前綴碼:對每一個字符規(guī)定一個0,1串作為其代碼,并要求任一字符的代碼都不是其他字符代碼的前綴。這種編碼稱為前綴碼。編碼的前綴性質(zhì)可以使譯碼方法非常簡單;例如001011101可以唯一的分解為0,0,101,1101,因而其譯碼為aabe。 譯碼過程需要方便的取出編碼的前綴,因此需要表示前綴碼的合適的數(shù)據(jù)結(jié)構(gòu)。為此,可以用二叉樹作為前綴碼的數(shù)據(jù)結(jié)構(gòu):樹葉表示給定字符;從樹根到樹葉的路徑當(dāng)作該字符的前綴碼;代碼中每一位的0或1分別作為指示某節(jié)點(diǎn)到左兒子或右兒子的“路標(biāo)”。 從上圖可以看出
3、,表示最優(yōu)前綴碼的二叉樹總是一棵完全二叉樹,即樹中任意節(jié)點(diǎn)都有2個兒子。圖a表示定長編碼方案不是最優(yōu)的,其編碼的二叉樹不是一棵完全二叉樹。在一般情況下,若C是編碼字符集,表示其最優(yōu)前綴碼的二叉樹中恰有|C|個葉子。每個葉子對應(yīng)于字符集中的一個字符,該二叉樹有|C|-1個內(nèi)部節(jié)點(diǎn)。 給定編碼字符集C及頻率分布f,即C中任一字符c以頻率f(c)在數(shù)據(jù)文件中出現(xiàn)。C的一個前綴碼編碼方案對應(yīng)于一棵二叉樹T。字符c在樹T中的深度記為dT(c)。dT(c)也是字符c的前綴碼長。則平均碼長定義為:使平均碼長達(dá)到最小的前綴碼編碼方案稱為C的最優(yōu)前綴碼。 2、構(gòu)造哈弗曼編碼 哈夫曼提出構(gòu)造最優(yōu)前綴碼的貪心算法,
4、由此產(chǎn)生的編碼方案稱為哈夫曼編碼。其構(gòu)造步驟如下: (1)哈夫曼算法以自底向上的方式構(gòu)造表示最優(yōu)前綴碼的二叉樹T。 (2)算法以|C|個葉結(jié)點(diǎn)開始,執(zhí)行|C|1次的“合并”運(yùn)算后產(chǎn)生最終所要求的樹T。 (3)假設(shè)編碼字符集中每一字符c的頻率是f(c)。以f為鍵值的優(yōu)先隊(duì)列Q用在貪心選擇時有效地確定算法當(dāng)前要合并的2棵具有最小頻率的樹。一旦2棵具有最小頻率的樹合并后,產(chǎn)生一棵新的樹,其頻率為合并的2棵樹的頻率之和,并將新樹插入優(yōu)先隊(duì)列Q。經(jīng)過n1次的合并后,優(yōu)先隊(duì)列中只剩下一棵樹,即所要求的樹T。 構(gòu)造過程如圖所示: 具體代碼實(shí)現(xiàn)如下: (1)4d4.cpp,程序主文件cppview plain
5、copy1. /4d4貪心算法哈夫曼算法2. #includestdafx.h3. #includeBinaryTree.h4. #includeMinHeap.h5. #include6. usingnamespacestd;7. 8. constintN=6;9. 10. templateclassHuffman;11. 12. template13. BinaryTreeHuffmanTree(Typef,intn);14. 15. template16. classHuffman17. 18. friendBinaryTreeHuffmanTree(Type,int);19. publ
6、ic:20. operatorType()const21. 22. returnweight;23. 24. /private:25. BinaryTreetree;26. Typeweight;27. ;28. 29. intmain()30. 31. charc=0,a,b,c,d,e,f;32. intf=0,45,13,12,16,9,5;/下標(biāo)從1開始33. BinaryTreet=HuffmanTree(f,N);34. 35. cout各字符出現(xiàn)的對應(yīng)頻率分別為:endl;36. for(inti=1;i=N;i+)37. 38. coutci:fi;39. 40. couten
7、dl;41. 42. cout生成二叉樹的前序遍歷結(jié)果為:endl;43. t.Pre_Order();44. coutendl;45. 46. cout生成二叉樹的中序遍歷結(jié)果為:endl;47. t.In_Order();48. coutendl;49. 50. t.DestroyTree();51. return0;52. 53. 54. template55. BinaryTreeHuffmanTree(Typef,intn)56. 57. /生成單節(jié)點(diǎn)樹58. Huffman*w=newHuffmann+1;59. BinaryTreez,zero;60. 61. for(inti=
8、1;i=n;i+)62. 63. z.MakeTree(i,zero,zero);64. wi.weight=fi;65. wi.tree=z;66. 67. 68. /建優(yōu)先隊(duì)列69. MinHeapHuffmanQ(n);70. for(inti=1;i=n;i+)Q.Insert(wi);71. 72. /反復(fù)合并最小頻率樹73. Huffmanx,y;74. for(inti=1;in;i+)75. 76. x=Q.RemoveMin();77. y=Q.RemoveMin();78. z.MakeTree(0,x.tree,y.tree);79. x.weight+=y.weight
9、;80. x.tree=z;81. Q.Insert(x);82. 83. 84. x=Q.RemoveMin();85. 86. deletew;87. 88. returnx.tree;89. (2)BinaryTree.h 二叉樹實(shí)現(xiàn)cppview plaincopy1. #include2. usingnamespacestd;3. 4. template5. structBTNode6. 7. Tdata;8. BTNode*lChild,*rChild;9. 10. BTNode()11. 12. lChild=rChild=NULL;13. 14. 15. BTNode(cons
10、tT&val,BTNode*Childl=NULL,BTNode*Childr=NULL)16. 17. data=val;18. lChild=Childl;19. rChild=Childr;20. 21. 22. BTNode*CopyTree()23. 24. BTNode*nl,*nr,*nn;25. 26. if(&data=NULL)27. returnNULL;28. 29. nl=lChild-CopyTree();30. nr=rChild-CopyTree();31. 32. nn=newBTNode(data,nl,nr);33. returnnn;34. 35. ;3
11、6. 37. 38. template39. classBinaryTree40. 41. public:42. BTNode*root;43. BinaryTree();44. BinaryTree();45. 46. voidPre_Order();47. voidIn_Order();48. voidPost_Order();49. 50. intTreeHeight()const;51. intTreeNodeCount()const;52. 53. voidDestroyTree();54. voidMakeTree(TpData,BinaryTreeleftTree,BinaryT
12、reerightTree);55. voidChange(BTNode*r);56. 57. private:58. voidDestroy(BTNode*&r);59. voidPreOrder(BTNode*r);60. voidInOrder(BTNode*r);61. voidPostOrder(BTNode*r);62. 63. intHeight(constBTNode*r)const;64. intNodeCount(constBTNode*r)const;65. ;66. 67. template68. BinaryTree:BinaryTree()69. 70. root=N
13、ULL;71. 72. 73. template74. BinaryTree:BinaryTree()75. 76. 77. 78. 79. template80. voidBinaryTree:Pre_Order()81. 82. PreOrder(root);83. 84. 85. template86. voidBinaryTree:In_Order()87. 88. InOrder(root);89. 90. 91. template92. voidBinaryTree:Post_Order()93. 94. PostOrder(root);95. 96. 97. template98
14、. intBinaryTree:TreeHeight()const99. 100. returnHeight(root);101. 102. 103. template104. intBinaryTree:TreeNodeCount()const105. 106. returnNodeCount(root);107. 108. 109. template110. voidBinaryTree:DestroyTree()111. 112. Destroy(root);113. 114. 115. template116. voidBinaryTree:PreOrder(BTNode*r)117.
15、 118. if(r!=NULL)119. 120. coutdatalChild);122. PreOrder(r-rChild);123. 124. 125. 126. template127. voidBinaryTree:InOrder(BTNode*r)128. 129. if(r!=NULL)130. 131. InOrder(r-lChild);132. coutdatarChild);134. 135. 136. 137. template138. voidBinaryTree:PostOrder(BTNode*r)139. 140. if(r!=NULL)141. 142.
16、PostOrder(r-lChild);143. PostOrder(r-rChild);144. coutdata;145. 146. 147. 148. template149. intBinaryTree:NodeCount(constBTNode*r)const150. 151. if(r=NULL)152. return0;153. else154. return1+NodeCount(r-lChild)+NodeCount(r-rChild);155. 156. 157. template158. intBinaryTree:Height(constBTNode*r)const15
17、9. 160. if(r=NULL)161. return0;162. else163. 164. intlh,rh;165. lh=Height(r-lChild);166. rh=Height(r-rChild);167. return1+(lhrh?lh:rh);168. 169. 170. 171. template172. voidBinaryTree:Destroy(BTNode*&r)173. 174. if(r!=NULL)175. 176. Destroy(r-lChild);177. Destroy(r-rChild);178. deleter;179. r=NULL;18
18、0. 181. 182. 183. template184. voidBinaryTree:Change(BTNode*r)/將二叉樹bt所有結(jié)點(diǎn)的左右子樹交換185. 186. BTNode*p;187. if(r)188. p=r-lChild;189. r-lChild=r-rChild;190. r-rChild=p;/左右子女交換191. Change(r-lChild);/交換左子樹上所有結(jié)點(diǎn)的左右子樹192. Change(r-rChild);/交換右子樹上所有結(jié)點(diǎn)的左右子樹193. 194. 195. 196. template197. voidBinaryTree:MakeT
19、ree(TpData,BinaryTreeleftTree,BinaryTreerightTree)198. 199. root=newBTNode();200. root-data=pData;201. root-lChild=leftTree.root;202. root-rChild=rightTree.root;203. (3)MinHeap.h 最小堆實(shí)現(xiàn)cppview plaincopy1. #include2. usingnamespacestd;3. template4. classMinHeap5. 6. private:7. T*heap;/元素數(shù)組,0號位置也儲存元素8.
20、 intCurrentSize;/目前元素個數(shù)9. intMaxSize;/可容納的最多元素個數(shù)10. 11. voidFilterDown(constintstart,constintend);/自上往下調(diào)整,使關(guān)鍵字小的節(jié)點(diǎn)在上12. voidFilterUp(intstart);/自下往上調(diào)整13. 14. public:15. MinHeap(intn=1000);16. MinHeap();17. boolInsert(constT&x);/插入元素18. 19. TRemoveMin();/刪除最小元素20. TGetMin();/取最小元素21. 22. boolIsEmpty(
21、)const;23. boolIsFull()const;24. voidClear();25. ;26. 27. template28. MinHeap:MinHeap(intn)29. 30. MaxSize=n;31. heap=newTMaxSize;32. CurrentSize=0;33. 34. 35. template36. MinHeap:MinHeap()37. 38. deleteheap;39. 40. 41. template42. voidMinHeap:FilterUp(intstart)/自下往上調(diào)整43. 44. intj=start,i=(j-1)/2;/i
22、指向j的雙親節(jié)點(diǎn)45. Ttemp=heapj;46. 47. while(j0)48. 49. if(heapi=temp)50. break;51. else52. 53. heapj=heapi;54. j=i;55. i=(i-1)/2;56. 57. 58. heapj=temp;59. 60. 61. template62. voidMinHeap:FilterDown(constintstart,constintend)/自上往下調(diào)整,使關(guān)鍵字小的節(jié)點(diǎn)在上63. 64. inti=start,j=2*i+1;65. Ttemp=heapi;66. while(j=end)67.
23、68. if(jheapj+1)69. j+;70. if(temp=heapj)71. break;72. else73. 74. heapi=heapj;75. i=j;76. j=2*j+1;77. 78. 79. heapi=temp;80. 81. 82. template83. boolMinHeap:Insert(constT&x)84. 85. if(CurrentSize=MaxSize)86. returnfalse;87. 88. heapCurrentSize=x;89. FilterUp(CurrentSize);90. 91. CurrentSize+;92. returntrue;93. 94. 95. template96. TMinHeap:RemoveMin()97. 98. Tx=heap0;99. heap0=heapCurrentSize-1;100. 101. CurrentSize-;102. FilterDown(0,CurrentSize-1);/調(diào)整新的根節(jié)點(diǎn)103. 104. returnx;105. 106. 107. template108. TMinHeap:GetMin()109. 110. returnhe
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 攝影合同中合同價款調(diào)整對價
- 校園綠化草坪翻新合同
- 酒店裝修工程協(xié)議
- 宗教建筑塔吊信號工錄用協(xié)議
- 滑翔傘班組施工合同
- 展會現(xiàn)場保安招聘合同
- 房屋交易爭議預(yù)防補(bǔ)充協(xié)議
- 商業(yè)街區(qū)廣告位外墻體租賃合同
- 酒店改造粉墻施工合同
- 家政公司文職人員招聘協(xié)議
- 9.2提高防護(hù)能力(課件)-2024-2025學(xué)年統(tǒng)編版道德與法治七年級上冊
- 汽車修理業(yè)務(wù)受理程序、服務(wù)承諾、用戶抱怨制度
- 2025屆福建省廈門市外國語學(xué)校高二數(shù)學(xué)第一學(xué)期期末考試試題含解析
- 貴陽一中2025屆高三10月高考適應(yīng)性月考(二) 思想政治試卷(含答案)
- 建筑垃圾消納處置場所建設(shè)可行性研究報告
- GB/T 44670-2024殯儀館職工安全防護(hù)通用要求
- 期中高頻易錯卷(試題)-2024-2025學(xué)年數(shù)學(xué)五年級上冊北師大版
- 2024江蘇省沿海開發(fā)集團(tuán)限公司招聘23人高頻500題難、易錯點(diǎn)模擬試題附帶答案詳解
- 2024年鹿城區(qū)區(qū)屬國企業(yè)面向社會和面向退役士兵公開招聘(選調(diào))工作人員高頻考題難、易錯點(diǎn)模擬試題(共500題)附帶答案詳解
- 7《兩件寶》(教學(xué)設(shè)計(jì))2024-2025學(xué)年統(tǒng)編版語文一年級上冊
- 外墻亮化工程施工方案
評論
0/150
提交評論