哈夫曼樹

題目描述

哈夫曼樹,第一行輸入一個數n,表示葉結點的個數。需要用這些葉結點生成哈夫曼樹,根據哈夫曼樹的概念,這些結點有權值,即weight,題目需要輸出所有結點的值與權值的乘積之和。

輸入描述:

輸入有多組數據。
每組第一行輸入一個數n,接着輸入n個葉節點(葉節點權值不超過100,2<=n<=1000)。

輸出描述:

輸出權值。
示例1

輸入

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;
}

        

發佈了112 篇原創文章 · 獲贊 7 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章