快速入手优先队列
创始人
2025-05-31 17:00:34

一.理解优先队列

标准模板库(Standard Template Library,STL)

C++功能强大,为开发者提供了标准模板库,其中封装了很多实用的容器。容器可以理解成能够实现很多功能的系统函数,或者说用来存放数据的对象,开发者可以根据接口规范(调用格式)直接调用,而不用关心其内部实现的原理和具体代码,十分方便快捷。

常见的容器有vector、stack、queue、map、set等。

优先队列(priority_queue)

STL 的容器中还有两种容器与队列有关,分别是双端队列(deque)和优先队列(priority_queue)。

priority_queue翻译为优先队列,一般用来解决一些贪心问题,其底层是用“堆”来实现的。

在优先队列中,任何时刻,队首元素一定是当前队列中优先级最高(优先值最大)的那一个(大根堆),也可以是最小的那一个(小根堆)。

可以不断往优先队列中添加某个优先级的元素,也可以不断弹出优先级最高的那个元素,每次操作其会自动调整结构,始终保证队首元素的优先级最高。

二.优先队列定义

定义和使用priority_queue前,也只要添加queue头文件(#include)。定义一个priority_queue的方法为:

priority_queue name;

其中,typename可以是任何基本类型或者容器,name为优先队列的名字。通过top()或pop()访问队首元素(也称堆顶元素),也就是优先级最高的元素。对于可以直接使用的基本数据类型(int等),优先队列对它们的优先级设置一般是数字越大的优先级越高(对于char,则是字典序最大的)。

三.prtority_queue的常用函数

(1)push()

push(x)是将x加入优先队列,时间复杂度为O(logn),n为当前优先队列中的元素个数。加入后会自动调整priority_queue的内部结构,以保证队首元素(堆顶元素)的优先级最高。

(2)top()

top)是获得队首元素(堆顶元素),时间复杂度为O(1)。

(3)pop()

popO是让队首元素(堆顶元素)出队,时间复杂度为O(logn),n为当前优先队列中的元素个数。出队后会自动调整priority_queue的内部结构,以保证队首元素(堆顶元素)的优先级最高。

四.定义排列方式

默认优先队列中的元素按照从大到小的顺序排列;若想从小到大排列有三种方法

  1. 输出元素乘以-1

  1. 利用C++funtional函数

  1. 与sort()函数类似,自己定义函数指针/函数对象/函数类模版对象

priority_queue q1; //定义heap为一个int类型的优先队

priority_queue q2; //定义k为一个double类型的优先队列

这两种定义方式都是大根堆,想要使其变成小根堆,可以将每个数据都乘以-1,输出再乘回-1

priority_queue,greater >que3;//注意“>>”会被认为错误,所以中间要加上空格

priority_queue,less >que4;最大值优先

五.greater与less

很多人greater和less会混淆,其实虽然greater有更大的意思,但构建的是小顶堆,可我们换个角度想,这个小顶堆弹出去的都是小的,留下来的就是更大的了!

这有个例题方便理解

题目

问题描述:给定n个正整数,删除最大的n1个数和最小的n2个数,并计算其余正整数的平均值。
·输入:输入由多组测试用例组成。每组测试用例由两行组成。
第一行包含三个整数n1,n2和n(1<=n1,n2<=10,n1+n2输出:对于每组测试用例,输出删除相关元素后的平均值,并将其四舍五入到小数点后6位。

分析

·本题的数据规模很大,如果通过排序获取相关区间的元素,计算累加和,肯定会因为时间效率太低而超时。
可以采用这样的方法:引入一个大根堆和一个小根堆,输入给定的数,使大根堆保存最大的n1个数,小根堆保存最小的n2个数,再算出所有的数的总和sum。随后,将sum减去大根堆里的元素和小根堆里的元素,再计算平均数。

代码

int main(){int n1, n2, n, x;while (scanf("%d %d %d", &n1, &n2, &n) && n > 0){priority_queue, greater >qsmall;//小根堆,保存最大的n1个数priority_queue, less >qbig;//大根堆,保存最小的n2个数double sum = 0.0;for (int i = 0; i < n; i++){ //遍历所有的元素scanf("%d", &x);sum += x;qsmall.push(x);qbig.push(x);if (qsmall.size() > n2)qsmall.pop();//保存最大的n1个数if (qbig.size()>n2)qbig.pop();//保存最小的n2个数}}
//n1+n2

~感谢观看❥(^_-)

相关内容

热门资讯

出行同意书公证:未成年人跨境旅... 当小明兴奋地整理着去法国参加夏令营的行李时,他的父母却在处理一件看似简单却至关重要的文件——出行同意...
旅途别只顾拍照!调动感官,才真... 旅行途中,能吸引我们的,常常是那些进入我们视线的自然或者人文景观。然而,“风景”可不单单只是明信片上...
宠物食品:主粮生产工艺分析(4... 本文为节选内容,更多报告,关注公众号:大消费市场调研 工艺:生产工艺持续迭代,新工艺粮增速较快 在“...
15个大厨不外传的做菜小技巧,... 💬 你是否曾经羡慕身边那些做饭特别好吃的朋友?他们总能用简单的食材,做出令人垂涎的美味佳肴。其实,做...