[LeetCode刷题笔记] C++ priority_queue常用操作

在[1]对常用的STL容器进行了概览,笔者在刷题过程中经常需要查询一些STL容器的函数,实为不便,因此在此对STL容器中常用的操作进行笔记。


std::priority_queue<T>定义于头文件<queue>中,是所谓的优先队列,一般的队列,如同[2]中所示,是先进先出的,不需要对插入对象的大小或者其他属性进行排序等,而优先队列可以提供插入对象与现存对象之间的比较机制,这种机制可以给每个元素提供优先级,从而在队列出列时,可以按照优先级的大小,升序或者降序出列。这种机制在实现操作系统的ready进程出列,给CPU运算时经常使用,因为不同的进程是有优先级的,经常需要按照进程的优先级进行出列。

注意到priority_queue<T>并不是一种原生的序列数据结构,而是一种容器类序列数据结构,其意思是,实现优先队列的底层数据结构可以是vector<T>,也可以是deque<T>,只要是满足可以定义以下函数的数据类型都行:front(), push_back(), pop_back()

其类原型如:

template<
    class T,
    class Container = std::vector<T>,
    class Compare = std::less<typename Container::value_type>
> class priority_queue;

这里的Container就是在指定容器类型,默认是用vector<T>实现的;Compare指定比较元素的方法,默认是less<T>降序,这里的less<T>的意思是最大优先级的元素将会在top()出现,而相反的,greater<T>的意思是最小优先级的元素将会在top()出现。 注意到,优先队列可以对最大或者最小优先级的元素在常数时间内的查找,但是插入和删除时间都是对数级别的。 其常用操作也不多,如下例子所示:

  1. push() 插入元素,并且对底层容器排序
  2. pop() 弹出栈顶元素,注意不返回值
  3. top() 返回栈顶元素,注意不弹出
  4. empty() 判断队列是否为空
  5. size() 返回队列尺寸
priority_queue<int, vector<int>, less<int>> lessq;
priority_queue<int, vector<int>, greater<int>> greatq;

vector<int> nums = {2,3,6,8,0,1,5}; // 假设数值大小表示每个元素的优先级
for (auto &n:nums) {
	lessq.push(n);
	greatq.push(n);
}
while (!lessq.empty()){
	cout << lessq.top() << " ";
	lessq.pop();
} // 输出 8,6,5,3,2,1,0 大优先级的先出列

while (!greatq.empty()){
	cout << greatq.top() << " ";
	greatq.pop(); 
} // 输出 0,1,2,3,5,6,8 小优先级的先出列

也可以自定义比较函数:

struct node {
	int x, y;
	node(int x, int y):x(x), y(y){}
};
struct cmp {
	bool operator()(node a, node b){
		if (a.x == b.x) return a.y >= b.y;
		else return a.x > b.x;
	}
};


int main() {
	priority_queue<node, vector<node>, cmp> pq;
	for(int i = 1; i <= 5; i++)
		for(int j = 1; j <= 5; j++)
	    	pq.push(node(i,j));
	while (!pq.empty()) {
	        cout << pq.top().x <<" " << pq.top().y <<endl;
	        pq.pop();
	 }
	 return 0;
}

输出如:
在这里插入图片描述
我们可以发现,priority_queue<T>是一个最大堆,其默认使用std:less<T>,也就意味着,其使用了操作符operator<。这意味着如果这个比较返回false,那么第一个参数的元素位置将会和top()更接近[4]。
因此 less<int>等价于下面的自定义比较结构cmp

struct cmp {
	bool operator()(int a, int b) {
		return a < b; // 这里是小于号,也即是为什么叫`less`的原因,但是其实最大优先级的先出列。
	}
}

Reference

[1]. https://blog.csdn.net/LoseInVain/article/details/104189784
[2]. https://blog.csdn.net/LoseInVain/article/details/104453697
[3]. https://stackoverflow.com/questions/16111337/declaring-a-priority-queue-in-c-with-a-custom-comparator
[4]. https://stackoverflow.com/questions/36069276/what-does-the-return-value-of-a-priority-queue-custom-comparator-signify

发布了127 篇原创文章 · 获赞 219 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/LoseInVain/article/details/104455380