詳解C++ STL priority_queue 容器
本篇隨筆簡單介紹一下\(C++STL\)中\(priority_queue\)容器的使用方法和常見的使用技巧。
priority_queue容器的概念
\(priority_queue\)在英文中是優先隊列的意思。
隊列是一種基本的數據結構。其實現的基本示意圖如下所示:
而\(C++STL\)中的優先隊列就是在這個隊列的基礎上,把其中的元素加以排序。其內部實現是一個二叉堆。所以優先隊列其實就是把堆模板化,將所有入隊的元素排成具有單調性的一隊,方便我們調用。
priority_queue容器的聲明
\(priority_queue\)容器存放在模板庫:#include<queue>
里,使用前需要先開這個庫。
這里需要注意的是,優先隊列的聲明與一般\(STL\)模板的聲明方式並不一樣。事實上,我認為其是\(C++STL\)中最難聲明的一個容器。
大根堆聲明方式:
大根堆就是把大的元素放在堆頂的堆。優先隊列默認實現的就是大根堆,所以大根堆的聲明不需要任何花花腸子,直接按\(C++STL\)的聲明規則聲明即可。
#include<queue>
priority_queue<int> q;
priority_queue<string> q;
priority_queue<pair<int,int> > q;
\(C++\)中的\(int,string\)等類型可以直接比較大小,所以不用我們多操心,優先隊列自然會幫我們實現。但是如果是我們自己定義的結構體,就需要進行重載運算符了。關於重載運算符的講解,請參考這篇博客:
小根堆聲明方式
大根堆是把大的元素放堆頂,小根堆就是把小的元素放到堆頂。
實現小根堆有兩種方式:
第一種是比較巧妙的,因為優先隊列默認實現的是大根堆,所以我們可以把元素取反放進去,因為負數的絕對值越小越大,那么絕對值較小的元素就會被放在前面,我們在取出的時候再取個反,就瞞天過海地用大根堆實現了小根堆。
第二種:
小根堆有自己的聲明方式,我們記住即可(我也說不明白道理):
priority_queue<int,vector<int>,greater<int> >q;
注意,當我們聲明的時候碰到兩個"<"或者">"放在一起的時候,一定要記得在中間加一個空格。這樣編譯器才不會把兩個連在一起的符號判斷成位運算的左移/右移。
priority_queue容器的使用方法
\(priority_queue\)容器的使用方法大致如下表所示:
用法 | 作用 |
---|---|
q.top() |
返回priority_queue的首元素 |
q.push() |
向priority_queue中加入一個元素 |
q.size() |
返回priority_queue當前的長度(大小) |
q.pop() |
從priority_queue末尾刪除一個元素 |
q.empty() |
返回priority_queue是否為空,1為空、0不為空 |
注意:priority_queue取出隊首元素是使用\(top\),而不是\(front\),這點一定要注意!!