C++ priority_queue

本文介绍了C++STL中的priority_queue数据结构,它是基于堆的实现,用于快速获取并按优先级排序元素。文章详细讲解了如何使用priority_queue进行topk排序,以及如何自定义模拟实现堆的调整方法。
摘要由CSDN通过智能技术生成

priority_queue也叫优先级队列,说是叫队列,实际上是一个堆。

priority_queue的接口:

 这些接口可以直接使用vector作为底层来使用:

 为什么说priority_queue是堆呢,写一段如下代码:

void priority()
{
    priority_queue<int> pq;
    pq.push(1);
    pq.push(2);
    pq.push(3);
    pq.push(4);


    while (!pq.empty())
    {
        cout << pq.top() << " ";
        pq.pop();
    }cout << endl;
}

 main函数调用运行:

 发现结果自己按照大堆排序了,它可以排序的原因是因为它的底层是堆,用了堆的向上调整,向下调整。

 可以大堆排序就可以小堆排序。priority_queue的模版里可以传三个实例:我们需要再往模版里再传个vector实例,再传个排序实例,升序是great,降序是less:

priority_queue<int,vector<int>,greater<int>> pq;

除了用vector作为实例还可以用deque,因为priority_queue的底层是堆,堆的向上向下调整是用下标进行调整的,deque也有operator[ ]。

课习题215. 数组中的第K个最大元素 - 力扣(LeetCode)

215. 数组中的第K个最大元素 - 力扣(LeetCode)

首先用队列进行一下排序,也就是topk排序,排出最大的前k个:

 然后把数组传给我们的pq;

priority_queue有个构造函数可以传区间:

 把nums传进来:

 第二步:第四步,返回顶部:

 测试未通过:

 分析:要找第二大的,只需要把第一大的去掉就-行了,所以k只减一次就够了,而不是减几次,所以应该是--k,而不是k--:

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int> pq(nums.begin(),nums.end());
        while(--k)
        {
             pq.pop();
        }
       return pq.top();
    }
};

模拟实现priority_queue

首先写一下push:

#include<queue>
namespace bitt
{
	template<class T,class Containter=vector<T> >
	class priority_queue
	{
	public:

		void push(int child); 
		{

		}
	private:
		Container _con;

};
}

根据我们写堆的经验堆里面进行增删查改是怎么弄的?

例如这样的一个堆:假设我们要在末尾插入一个20:

_con.push_back(x);

那它就不是一个堆了,要想让它还是保持为一个堆需要写一个向上调整函数。

	
		void adjust_queue(int child)
		{
			
			int parent = (child - 1 )/ 2;
			while (child > 0)
			{
		           if (_con[parent] >_con[ child])
					{
						swap(_con[parent],_con[child]);
						child = parent;
						parent = (child - 1) / 2;
					}
					else
					{
						break;
					}
			}
		
		
	}

然后是删除值,删除值是先把头尾交换一下:

然后用向下调整法进行调整法 :

然后在写一些size(),empty(),top():


		const T& top()
		{
			return _con[0];
		}

		bool empty()
		{
			return _con.empty();
		}

		size_t size()
		{
			return _con.size();
		}

 main函数调用运行:


void test111()
{

    bitt::priority_queue<int> pq;
    pq.push(1);
    pq.push(2);
    pq.push(3);
    pq.push(4);
    pq.push(5);


    while (!pq.empty())
    {
        cout << pq.top() << " ";
        pq.pop();
    } cout << endl;


}
int main()
{
    test111();
}

虽然可以运行正确,但是会报错:因为底层是vector,用的下标访问,下标一旦越界,就会报断言警告。

最后发现是向下调整的问题,改一下:

就可以正常运行不报错了:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孙鹏宇.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值