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

原创文章 35 获赞 17 访问量 7834

猜你喜欢

转载自blog.csdn.net/dear_jing/article/details/105940899