|
我想每個計算機專業(yè)的學生或多或少都接觸過哈夫曼編碼,數(shù)據結構中的老問題了。大體就是給出一些字符,和這些字符的出現(xiàn)頻率,讓你為這些字符設計一個二進制編碼,要求頻率最高的字符的編碼最短。解決的方法是構造一棵哈夫曼樹(二叉樹),其基本思路是,每次從這些字符中挑出兩個頻率最低的,然后構造一個新的結點,使新結點的左右孩子指針分別指向那兩個節(jié)點。我想這個大家都很清楚了,我就不多說了。主要講下這次我用C++實現(xiàn)時遇到的問題。首先,我定義了一個哈夫曼樹結點: class hNode 僅僅只是存放數(shù)據的對象,所以只有一個構造函數(shù),并且所有的data member都是公有的。 初步的設想是這樣的,先把所有的hNode對象都壓入優(yōu)先隊列中去,然后每次彈出兩個,組成一個新的結點,再把新的結點壓入隊列,重復這一步驟,當隊列中只有一個元素時,哈夫曼樹也就完成了。像這樣:(是錯的,可別學) while(...) 然而遭遇的第一個問題是,STL的所有容器的的插入都是基于by value語義的,也就是要生成一個對象的副本放在容器中。這樣的后果就是hNode的left,right指針都指到不知道什么地方去了。大家可以稍微畫幾個圖試一下,就知道出了什么問題了??紤]一下后,發(fā)現(xiàn)如果隊列里存放hNode的指針,就不會出現(xiàn)這個問題了,于是改寫成: hNode* makeTree(priority_queue<hNode*> pq) 然而馬上遭遇了第二個問題。std::priority_queue在判斷優(yōu)先關系的時候,直接比較指針的地址,而不是指針指向的對象的大小關系。而指針不是類,我沒辦法重寫指針的比較操作。程序陷入了困境之中。std::priority_queue默認使用Greater<>模板來生成一個function object來對元素進行比較,我試圖為Greater<>寫一個hNode*的特化版本來改變優(yōu)先隊列對hNode*的比較,然而也沒有成功。山重水復疑無路之時,突然想到為什么不直接為優(yōu)先隊列寫一個function object來替代Greater<>不就可以了嗎?趕快寫下如下代碼: struct phNodeComp 然后把std::priority_queue的申明變?yōu)椋?/p> priority_queue<hNode*,vector<hNode*>,phNodeComp > pq; 終于把這個問題給解決了??礃幼觾H從書本上獲得的知識是不牢靠的,一定要自己實踐了才會有真正的認識。 |
|
|
來自: 千鋒Python學堂 > 《程序員經驗分享》