C++隊列
默認已熟悉std::vector
。vector
是一個極其重要的模板,其中的每一個函數都應該了解其作用與用法,這里不再贅述。
雙向隊列
雙向隊列(std::deque
)類似於vector
,允許快速隨機訪問任何元素並在容器后面高效插入和刪除。 但是,和矢量不同的是, deque
還支持在容器前面高效插入和刪除。使用時需加入頭文件<deque>
deque
雖名為隊列,但是同時支持一些非隊列操作。比如,deque::insert
和deque::erase
可在deque
中的任意位置插入和刪除元素。其常用的幾個操作為deque::push_back
、deque::pop_back
、deque::push_front
和deque::pop_front
,用來在隊列頭尾進行插入刪除元素。
與 std::vector
相反, deque
的元素不是相接存儲的:典型實現用單獨分配的固定大小數組的序列,外加額外的登記,這表示下標訪問必須進行二次指針解引用,與之相比 vector 的下標訪問只進行一次(來自cppreference)。因此,相對於vector
,deque
沒有reserve
方法。
隊列
隊列(std::queue
)是一種先進先出的結構。相較與雙向隊列,它只保留了最必要的部分。默認使用deque
作為核心數據成員,可以改為list
。
構造函數示例:
std::deque<int> dque{ 1,2,3 };//deque,初始化列表,以下三個queue的核心數據成員類型,
std::queue<int, std::deque<int>> que0;//默認構造
std::queue<int, std::deque<int>> que2(que1);//復制構造
std::queue<int, std::deque<int>> que1(dque);//使用const container_type&構造
接口:
成員函數 | 說明 |
---|---|
back |
返回尾元素(最后添加的元素)的引用 |
empty |
返回bool ,隊列是否為空 |
front |
返回首元素的引用 |
pop |
無返回值,刪除頭元素 |
push |
無返回值,在隊列尾部添加一個元素 |
size |
返回size_t ,隊列中元素的個數 |
優先隊列
優先隊列(std::priority_queue
)是一種二叉堆結構,C++默認為最大堆。它不是先進先出,而是優先順序最大者先出。優先隊列默認使用vector
作為核心數據成員。優先隊列中某一節點的值要比其下所有節點值的優先順序更高。
下圖中的第一個子圖是一個優先隊列的示例,大值優先。隊首為6,不小於任意其它元素,是整個隊列的最大值。隊列中的任意節點都不小於其直接或間接子節點的值。

上圖演示了隊尾插入元素的過程,下圖演示了刪除隊首元素的過程。

若在第一步(右上圖)中交換首尾元素而不是進行替換,就使最大值排在最后的位置。然后把隊列的長度變量減1,不斷重復此過程,就可以得到一個升序的序列。此方法被稱為堆排序。
若從一個數組中構建一個優先隊列,可以使用第一幅圖中將元素一個個插入的方法,也可以使用如下的方法。

priority_queue
沒有back
接口,因為此位置的值是不確定的,有一個top
接口對應front
。
int a[] = { 1,5,2,3,6,4 };
std::priority_queue<int, std::vector<int>, std::less<int>>dat(a, a + 6);
上面示例使用數組a
中的元素構建了一個大值優先隊列。尖括號中第一個int
說明隊列元素類型,第二個vector<int>
說明隊列的數據成員使用的是vector
,最后一個less<int>
說明隊列是最大堆。less
是一個類模板,但是重載了小括號,其行為類似於函數。在下面的示例中可以看到其實現細節。
struct AA
{
int i;
char c;
//AA重載了小於,且兩個參數都是const的,否則less中不能填入AA類型
bool operator<(const AA& rval) const
{return c < rval.c;}
};
struct BB//BB沒有對操作符進行重載
{
int i;
char c;
};
std::priority_queue<AA, std::vector<AA>, std::less<AA> >pqAA;//char最大的排在隊首
struct grt//針對BB類設計的仿std::greater類
{
bool operator()(const BB& lval, const BB& rval)
{return lval.c > rval.c;}
};
std::priority_queue<BB, std::vector<BB>, grt>pqBB;//char最小的排在隊首
//BB的例子也可以這樣寫
auto cmp = [](const BB& lval, const BB& rval) {return lval.c > rval.c; };
std::priority_queue<BB, std::vector<BB>, decltype(cmp)>pqBB(cmp);
優先規則的確定在於,在尖括號中輸入一個類名,構造函數中給出該類的一個對象,使用該對象應該能夠對隊列中的元素進行比較。若構造函數中將其省略,默認造成的對象能否依舊完成此任務。對於grt
,其默認生成的對象也能進行BB
之間的比較,而對於lambda,它接收兩個const BB&
返回bool
。但如果定義一個此類型的對象,我們知道它可以對BB
進行比較,但是卻不知道比較規則,因此隊列構造函數中的的對應參數就不能省略。