9,8.1 哈夫曼树
将n个结点构建如下:
上图中,就说出了一个道理:即按照堆的方式,每次找到两个最小的值,然后将其相加,然后将其压入到队列中,再找出俩个最小的值相加,放到队列中依次循环
#include<iostream>
/*
题目的意思是输入n个值,然后输出最小的结点权值,就按照优先队列的方式
算出来结果是14还是30,我认为是14,不对答案是30,其实队列q已经是按照小顶堆的方式进行排列的,我们每次
只要将两个两个的值,从队列中弹出来->相加->在压进去就能得到最小权值,其实这个可以类似构建的过程中,
每次将队列中俩个最小的值相加,压入队列,再找俩个最小的值
//代表小顶堆的优先队列
priority_queue<long long, vector<long long>, greater<long long>> q;
main函数
1.int类型 n, long long类型 参数temp x,y ,ans初始值为0
2.输入n
3.for循环:循环n个
1.输入temp
2将temp压入到队列q中
4.while循环:队列中元素的个数>1
1.将队列的顶部元素,放到x中
2.弹出队列元素q
3.设置y为,当前队列的顶部元素
4.再次弹出
5.将x+y压入队列中
6.让ans+= x+y之和
5.最后输出ans
*/
#include<queue> //包含小顶堆的库函数
/*
priority_queue<Type, Container, Functional>
Type为数据类型, Container为保存数据的容器,Functional为元素比较方式。
用operator,也就是优先队列是大顶堆,队头元素最大。
greater,也就是优先队列最小顶堆,对头元素最小
*/
using namespace std;
int main()
{
priority_queue<long long, vector<long long>,greater<long long>> q;
int n;
long long temp,x,y,ans=0;
cin >> n;
for(int i=0; i<n; i++)
{
cin >> temp;
q.push(temp); //一旦压入元素,就自动把最小值放到队头
}
while(q.size()>1)
{
x=q.top();
q.pop();
y=q.top();
q.pop();
q.push(x+y);
ans+=x+y; //ans每次将队列中两两最小的值相加
}
cout << ans;
}
//将某些值需要压入队列q中,注意q的堆顶元素是q.top 弹出q.pop() 压入是q.push()
9.8.2 哈夫曼编码: