[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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章