C++隊列


C++隊列

默認已熟悉std::vectorvector是一個極其重要的模板,其中的每一個函數都應該了解其作用與用法,這里不再贅述。

雙向隊列

雙向隊列(std::deque)類似於vector,允許快速隨機訪問任何元素並在容器后面高效插入和刪除。 但是,和矢量不同的是, deque還支持在容器前面高效插入和刪除。使用時需加入頭文件<deque>

deque雖名為隊列,但是同時支持一些非隊列操作。比如,deque::insertdeque::erase可在deque中的任意位置插入和刪除元素。其常用的幾個操作為deque::push_backdeque::pop_backdeque::push_frontdeque::pop_front,用來在隊列頭尾進行插入刪除元素。

std::vector 相反, deque 的元素不是相接存儲的:典型實現用單獨分配的固定大小數組的序列,外加額外的登記,這表示下標訪問必須進行二次指針解引用,與之相比 vector 的下標訪問只進行一次(來自cppreference)。因此,相對於vectordeque沒有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,不小於任意其它元素,是整個隊列的最大值。隊列中的任意節點都不小於其直接或間接子節點的值。

push

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

pop

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

若從一個數組中構建一個優先隊列,可以使用第一幅圖中將元素一個個插入的方法,也可以使用如下的方法。

build

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進行比較,但是卻不知道比較規則,因此隊列構造函數中的的對應參數就不能省略。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM