2.2 哈夫曼樹(所有構造得到的中間結點權值和爲該哈夫曼樹的帶權路徑和)

哈夫曼樹

1、題目和要求

時間限制:1s,內存限制:32MB,特殊判題:否
在這裏插入圖片描述

2、總結

1)構建小頂堆。使用priority_queue<int> heap構建的堆默認是大頂堆,使用priority_queue<int,vector<int>,greater<int> > heap構建小頂堆。

2)有一個非常重要的概念:所有構造得到的中間結點(即哈夫曼樹上非葉子結點)權值和即爲該哈夫曼樹的帶權路徑和。記住這句話省了好多事……

3)有許多小細節需要注意:

  1. 取出小頂堆頂後,需判斷該值是否在輸入序列中。
  2. 需要考慮,如果相加後的值和輸入序列中的某個值相等怎麼辦。
3、思路
  1. 將數據輸入小頂堆
  2. 每次取小頂堆的頂,構建非葉子節點。同時採用數組存儲所有節點
  3. 輸出帶權路徑和
4、代碼
#include <iostream>
#include <queue>
using namespace std;

#define N 1000

class Node
{
private:
    int level;
    int value;

public:
    void setNode(int l,int v)
    {
        level = l;
        value = v;
    }

    int getLevel()
    {
        return level;
    }

    int getValue()
    {
        return value;
    }
};


int value[N];//value:記錄輸入數值

//用於判斷取出的小頂堆頂是否是輸入的數值。
//如果是則加入HaffmanTree[N];如果不是,則不加入
int exitOrnot(int length,int a)
{
    for(int i=0; i<length; i++)
    {
        if(value[i]==a)
        {
            value[i]=-1;
            return i;
        }
    }
}

int main()
{
    //1.將數據輸入小頂堆
    priority_queue< int,vector<int>,greater<int> > inputList;
    Node HaffmanTree[N],HaffmanNode1,HaffmanNode2;
    int nodeNumber,m;//nodeNumber:記錄結點個數
    int level=0,i=0;//level:記錄結點層數 i:記錄數組位置
    int p1,p2;//p1,p2:記錄相加的兩個結點的數值

    cin>>nodeNumber;
    m=0;
    while(m<nodeNumber)
    {
        cin>>value[m];
        inputList.push(value[m]);
        m++;
    }
    
    //2.每次取小頂堆的頂,構建節點,採用數組存儲所有節點
    while(i<nodeNumber)
    {
        HaffmanNode1.setNode(level,inputList.top());
        inputList.pop();

        HaffmanNode2.setNode(level,inputList.top());
        inputList.pop();

        p1 = exitOrnot (nodeNumber, HaffmanNode1.getValue());
        p2 = exitOrnot (nodeNumber, HaffmanNode2.getValue());
        if(p1>=0 && p1<nodeNumber)
        {
            HaffmanTree[i++].setNode(HaffmanNode1.getLevel(),HaffmanNode1.getValue());
        }

        if(p2>=0 && p2<nodeNumber)
        {
            HaffmanTree[i++].setNode(HaffmanNode2.getLevel(),HaffmanNode2.getValue());
        }

        inputList.push(HaffmanNode1.getValue() + HaffmanNode2.getValue());
        level++;
    }
    
//3.輸出
    int WPL=0;
    for(i=0; i<nodeNumber; i++)
    {
        WPL += HaffmanTree[i].getValue() * (nodeNumber - 1 - HaffmanTree[i].getLevel());
    }
    cout<<WPL<<endl;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章