【C++ ——— priority_queue】优先级队列


前言

此文让我们来认识学习priority_queue的知识
参考文档:https://legacy.cplusplus.com/reference/queue/priority_queue/


一、priority_queue构成

底层默认适配器使用的是vector默认生成的
优先级队列底层算法是使用的堆的算法生成的

在这里插入图片描述
构造:
在这里插入图片描述

主要接口
在这里插入图片描述

二、优先级队列使用

在这里插入图片描述
这里默认排序出大堆,想排序出小堆呢?
这里就要看priority_queue模板参数了
在这里插入图片描述
这里适配器默认给的是less
我们想要默认小堆就要是用greater(库里面有的)
(less和greater都是仿函数)
注意:less是大堆greater是小堆

less:
在这里插入图片描述

greater:
在这里插入图片描述

三、仿函数

我们上面说到的less和greater都是仿函数。
什么是仿函数呢?(有些地方也叫函数对象)
我们这样定义这个类

  1. less定义:
    在这里插入图片描述
    2.less使用
    在这里插入图片描述
    仿函数的功能上主要是为了替代函数指针。

四、模拟实现

(包含对仿函数的使用)有注释解释

  1. priority_queue.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<vector>

namespace goat
{
	priority_queue()
		{}

		//迭代器区间构造
	template<class InputIterator>
	priority_queue(InputIterator first,InputIterator last)
		:_con(first,last)
	{
			//建堆
		for (int i = (_con.size - 2) / 2; i >= 0; --i)
		{
			adjust_down(i);
		}
	}
	
	//less和greater模拟实现
	template<class T>
	class Less//优先级队列中less和greater是为了比较大小
	{
	public:
		bool operator()(const T& t1,const T& t2)
		{
			return t1 < t2;
		}
	};
	template<class T>
	class Greater
	{
	public:
		bool operator()(const T& t1, const T& t2)
		{
			return t1 > t2;
		}
	};

	//优先级队列模拟实现

	template<class T, class Container = vector<T>,class Compare = Less<T> >//这里默认传Less这个仿函数
	class priority_queue
	{
	public:

		void adjust_up(size_t child)
		{
			size_t parent = (child - 1) / 2;
			while (child > 0)
			{
				Compare com;

				
				if(com(_con[parent] , _con[child]))
				//if (_con[parent] < _con[child])当默认对象为less时这两个表达式是等价的
				{
					swap(_con[parent], _con[child]);
					child = parent;
					parent = (parent - 1) / 2;
				}
				else
				{
					break;
				}
			}
		}
		void adjust_down(size_t parent)
		{
			size_t child = parent * 2 + 1;
			Compare com;
			while (child < _con.size())
			{
				

				if (child + 1 < _con.size() 
					&& com(_con[child],_con[child + 1]))
					++child;
				//if(_con[parent] < _con[child])
				if(com(_con[parent], _con[child]))
				{
					swap(_con[parent], _con[child]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
				{
					break;
				}

			}
		}
		void push(const T& x)
		{
			_con.push_back(x);
			adjust_up(_con.size()-1);
		}
		void pop()
		{
			swap(_con[0], _con[_con.size()-1]);
			_con.pop_back();
			adjust_down(0);
		}
		const T& top()
		{
			return _con[0];
		}

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

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

	private:
		Container _con;
	};
}
  1. test.cpp
void test_priority_queue3()
{
	goat::priority_queue<int, vector<int>, goat::Less<int>> l;
	goat::priority_queue<int, vector<int>, goat::Greater<int>> g;
	                                        //注意这里传的是类型
	                                        

	l.push(8);
	l.push(0);
	l.push(5);
	l.push(12);
	l.push(1);

	g.push(8);
	g.push(0);
	g.push(5);
	g.push(12);
	g.push(1);


	cout << "less大堆比较,构造堆" << endl;
	while (!l.empty())
	{
		int i = l.top();
		l.pop();
		cout << i << " ";//大堆
	}
	cout << endl;
	cout << "greater小堆比较,构造堆" << endl;
	while (!g.empty())
	{
		int i = g.top();
		g.pop();
		cout << i << " ";//小堆
	}
	cout << endl;

}
int main()
{
	test_priority_queue3();
	return 0;
}

结果:
在这里插入图片描述

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值