題目描述
輸入描述:
輸入有多組數據。 每組第一行輸入一個數n,接着輸入n個葉節點(葉節點權值不超過100,2<=n<=1000)。
輸出描述:
輸出權值。
輸入
5 1 2 2 5 9
輸出
37
分析:
1.此題主要有兩個難點,一是如何構造哈夫曼樹;二是如何計算葉子節點權值和。
2.在構造哈夫曼樹時,學習瞭如何使用優先隊列priority_queue,其是一種可以自行排序的的隊列,簡單介紹可以參考這篇博客:
https://blog.csdn.net/c20182030/article/details/70757660
在構造優先隊列時,priority_queue <int,vector<int>,greater<int> > q;,期中vector<int>表示優先隊列是通過vector來實現的。
greater與less對應從小到大排列與從大到小排列。
3.分析哈夫曼樹,非葉子節點權值爲子節點權值之和,加上該非葉子節點的權值,相當於加上了以其爲根節點的所有葉子節點的權值。
當加上所有的非葉子節點的權值時,底層的葉子節點的權值就有了一種“累加”的效果,底層葉子節點所依附的非葉子節點越多,它累加的次數
就越多,也就是從根節點的路徑*其權值的效果。
所以:哈夫曼樹中,非葉子節點的權值和 即爲 該哈夫曼樹 葉子節點的帶權路徑和。
代碼:
#include <iostream>
#include <queue>
using namespace std;
int main()
{
int n,i;
int sum=0;
priority_queue<int,vector<int>,greater<int> >q;
cin>>n;
for(i=1;i<=n;i++)
{
int temp;
cin>>temp;
q.push(temp);
}
while(q.size()!=1)
{
int x = q.top();
q.pop();
int y = q.top();
q.pop();
sum += x + y;
q.push(x+y);
}
cout<<sum;
return 0;
}