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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值