C++最優(yōu)二叉樹哈夫曼樹算法解析
定義
哈夫曼樹又稱最優(yōu)二叉樹,是一種帶權(quán)路徑長度最短的二叉樹。
所謂樹的帶權(quán)路徑長度,就是樹中所有的葉結(jié)點的權(quán)值乘上其到根結(jié)點的路徑長度(若根結(jié)點為0層,葉結(jié)點到根結(jié)點的路徑長度為葉結(jié)點的層數(shù))。
樹的路徑長度是從樹根到每一結(jié)點的路徑長度之和,記為WPL=(W1*L1+W2*L2+W3*L3+...+Wn*Ln),N個權(quán)值Wi(i=1,2,...n)構(gòu)成一棵有N個葉結(jié)點的二叉樹,相應的葉結(jié)點的路徑長度為Li(i=1,2,...n)。
可以證明哈夫曼樹的WPL是最小的。
給定N個權(quán)值作為N個葉子結(jié)點,構(gòu)造一棵二叉樹,若該樹的帶權(quán)路徑長度達到最小,稱這樣的二叉樹為最優(yōu)二叉樹,也稱為哈夫曼樹(Huffman Tree)。
哈夫曼樹是帶權(quán)路徑長度最短的樹,權(quán)值較大的結(jié)點離根較近。
實例引入
現(xiàn)在有這樣一個經(jīng)典問題:果子合并。
現(xiàn)在得到很多果子,需要把這些果子合并成一堆。每一次合并,可以把兩堆果子合并到一起,消耗的體力等于兩堆果子的重量之和??梢钥闯?,所有的果子經(jīng)過 n−1 次合并之后,就只剩下一堆了。在合并果子時總共消耗的體力等于每次合并所耗體力之和。
假定每個果子重量都為 1,并且已知果子的種類數(shù)和每種果子的數(shù)目,你的任務是設計出合并的次序方案,使耗費的體力最少,并輸出這個最小的體力耗費值。
例如有 3 種果子,數(shù)目依次為 1,2,9??梢韵葘?nbsp;1、2 堆合并,新堆數(shù)目為 3,耗費體力為 3。
接著,將新堆與原先的第三堆合并,又得到新的堆,數(shù)目為 12,耗費體力為 12。所以總共耗費體力=3+12=15??梢宰C明 15 為最小的體力耗費值。
我們把這幾個果子看成樹的葉子
然后通過逐次合并其中兩個葉子(果子),使根節(jié)點的權(quán)值最小,根據(jù)上面的分析先合并1,2得到3,之后合并3,9得到12。
其中我們要計算的便是產(chǎn)生的新節(jié)點的權(quán)值,把這先權(quán)值相加,即是最后要求的體力值。
進一步分析可以發(fā)現(xiàn),假設初始狀態(tài)下我們有四個點,是四個點之間的最優(yōu)解問題,當我們合并其中兩個點之后就變成了三個點的最優(yōu)解問題,以此類推;
而且如果保證每次選的兩個數(shù)都是最小的(最優(yōu)的),那么接下來都是最優(yōu)解的情況了。
由于數(shù)據(jù)輸入是并不是按照從小到大排列,故可以使用小根堆來做。
代碼
#include <bits/stdc++.h> using namespace std; int main() { int n; scanf("%d", &n); priority_queue<int, vector<int>, greater<int>> heap; while (n--) { int x; scanf("%d", &x); heap.push(x); } int res = 0; while (heap.size() > 1) { int a = heap.top(); heap.pop(); int b = heap.top(); heap.pop(); res += a + b; heap.push(a + b); } printf("%d\n", res); return 0; }
到此這篇關于C++最優(yōu)二叉樹哈夫曼樹算法解析的文章就介紹到這了,更多相關C++哈夫曼樹內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Qt圖形圖像開發(fā)之曲線圖模塊QCustomplot庫生成靜態(tài)、動態(tài)曲線詳細教程圖解
這篇文章主要介紹了Qt圖形圖像開發(fā)之曲線圖模塊QCustomplot庫畫靜態(tài)、動態(tài)曲線詳細教程圖解,需要的朋友可以參考下2020-03-03C語言動態(tài)與靜態(tài)分別實現(xiàn)通訊錄詳細過程
這篇文章主要為大家介紹了C語言動態(tài)與靜態(tài)分別實現(xiàn)通訊錄,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-02-02淺談c++如何實現(xiàn)并發(fā)中的Barrier
這篇文章主要介紹了淺談c++如何實現(xiàn)并發(fā)中的Barrier,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-07-07Qt圖形圖像開發(fā)曲線圖表模塊QChart庫基本用法、各個類之間的關系說明
這篇文章主要介紹了Qt圖形圖像開發(fā)曲線圖表模塊QChart庫基本用法、各個類之間的關系說明,需要的朋友可以參考下2020-03-03