日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++中的deque、stack、queue及priority_queue

發(fā)布時間:2024/4/11 c/c++ 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++中的deque、stack、queue及priority_queue 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

C++中的deque、stack、queue及priority_queue

文章目錄

  • C++中的deque、stack、queue及priority_queue
    • 一、deque
    • 二、stack
    • 三、queue
    • 四、priority_queue
    • 五、相關(guān)注意事項

一、deque

  • 1 . deque的介紹
  • deque(發(fā)音類似“deck”),是雙端隊列不規(guī)則的首字母縮寫,雙端隊列是動態(tài)大小的序列式容器,其可以像兩端進(jìn)行伸縮。
  • 特定的庫可以以不同的方式實(shí)現(xiàn)deque,但通常都是一種動態(tài)數(shù)組。
  • 不論在何種情況下,它都允許通過隨機(jī)訪問迭代器直接訪問單個元素,可以根據(jù)需要動態(tài)的伸縮。
  • 因此,deque提供了一些與vector相似的功能,但deque在頭部和尾部進(jìn)行數(shù)據(jù)插入和刪除操作更加高效。
  • 與vector不同的是,deque不能保證所有的元素存儲在連續(xù)的空間中,在deque中通過指針加偏移量方式訪問元素可能會導(dǎo)致非法的操作。
  • vector與list提供了相似的接口,因此其具有類似的用途,但是內(nèi)部的實(shí)現(xiàn)原理不同:vector使用使用了動態(tài)數(shù)組,該數(shù)組通常需要動態(tài)增長;deque中的元素可能分散在不同的存儲塊中
  • 在deque中保存了一些必要的信息,通常用來在常數(shù)范圍內(nèi)直接訪問deque中的任何一個元素,所以deque的內(nèi)部實(shí)現(xiàn)比vector復(fù)雜,但是這些額外信息使得dque在某些情況下增長更加的高效,特別是在序列比較大,重新分配成本比較高的情況下。
  • 除了在頻繁在頭部或尾部進(jìn)行插入和刪除操作外,deque比list和forward_list的性能更差
    • 2 deque底層的原理圖

    • 3 .deque的應(yīng)用場景
    • deque在序列式容器中比較雞肋,因為如果只是簡單的存儲元素,使用vector即可
    • 如果對元素任意位置進(jìn)行插入或者刪除操作比較多,使用list即可
    • 所以一般很少去使用deque。deque最大的應(yīng)用,就是用其作為標(biāo)準(zhǔn)庫中stack和queue的底層結(jié)構(gòu)

    二、stack

    • 1.stack的介紹
  • stack是一種容器適配器,專門用在具有后進(jìn)先出操作的上下文環(huán)境中,其刪除只能從容器的一端進(jìn)行元素的插入與提取操作。
  • stack是作為容器適配器被實(shí)現(xiàn)的,容器適配器即是對特定類封裝作為其底層的容器,并提供一組特定的成員函數(shù)來訪問其元素,將特定類作為其底層的,元素特定容器的尾部(即棧頂)被壓入和彈出。
  • stack的底層容器可以是任何標(biāo)準(zhǔn)的容器類模板或者一些其他特定的容器類,這些容器類應(yīng)該支持以下操作:
  • empty:判空操作 back:獲取尾部元素操作 push_back:尾部插入元素操作 pop_back:尾部刪除元素操作
  • 標(biāo)準(zhǔn)容器vector、deque、list均符合這些需求,默認(rèn)情況下,如果沒有為stack指定特定的底層容器,默認(rèn)情況下使用deque。
    • 2.stack的模擬實(shí)現(xiàn)
    #include<deque>namespace wolf {template<class T, class Con = deque<T>>class stack{public:stack() {}void push(const T& x) {_c.push_back(x);}void pop() {_c.pop_back();}T& top() {return _c.back();}const T& top()const {return _c.back();}size_t size()const {return _c.size();}bool empty()const {return _c.empty();}private:Con _c;}; }

    三、queue

    • 1.queue的介紹
  • 隊列是一種容器適配器,專門用于在FIFO上下文(先進(jìn)先出)中操作,其中從容器一端插入元素,另一端提取元素。
  • 隊列作為容器適配器實(shí)現(xiàn),容器適配器即將特定容器類封裝作為其底層容器類,queue提供一組特定的成員函數(shù)來訪問其元素。元素從隊尾入隊列,從隊頭出隊列。
  • 底層容器可以是標(biāo)準(zhǔn)容器類模板之一,也可以是其他專門設(shè)計的容器類。該底層容器應(yīng)至少支持以下操作:
  • empty:檢測隊列是否為空 size:返回隊列中有效元素的個數(shù) front:返回隊頭元素的引用 back:返回隊尾元素的引用 push_back:在隊列尾部入隊列 pop_front:在隊列頭部出隊列
  • 標(biāo)準(zhǔn)容器類deque和list滿足了這些要求。默認(rèn)情況下,如果沒有為queue實(shí)例化指定容器類,則使用標(biāo)準(zhǔn)容器deque
    • 2.queue的模擬實(shí)現(xiàn)
    #include<deque>namespace wolf {template<class T, class Con = deque<T>>class queue{public:queue() {}void push(const T& x) {_c.push_back(x);}void pop() {_c.pop_front();}T& back() {return _c.back();}const T& back()const {return _c.back();}T& front() {return _c.front();}const T& front()const {return _c.front();}size_t size()const {return _c.size();}bool empty()const {return _c.empty();}private:Con _c;}; }

    四、priority_queue

    • 1.priority_queue的介紹
  • 優(yōu)先隊列是一種容器適配器,根據(jù)嚴(yán)格的弱排序標(biāo)準(zhǔn),它的第一個元素總是它所包含的元素中最大的。
  • 此上下文類似于堆,在堆中可以隨時插入元素,并且只能檢索最大堆元素(優(yōu)先隊列中位于頂部的元素)。
  • 優(yōu)先隊列被實(shí)現(xiàn)為容器適配器,容器適配器即將特定容器類封裝作為其底層容器類,queue提供一組特定的成員函數(shù)來訪問其元素。元素從特定容器的“尾部”彈出,其稱為優(yōu)先隊列的頂部。
  • 底層容器可以是任何標(biāo)準(zhǔn)容器類模板,也可以是其他特定設(shè)計的容器類。容器應(yīng)該可以通過隨機(jī)訪問迭代器訪問,并支持以下操作:
  • empty():檢測容器是否為空 size():返回容器中有效元素個數(shù) front():返回容器中第一個元素的引用 push_back():在容器尾部插入元素 pop_back():刪除容器尾部元素
    • 標(biāo)準(zhǔn)容器類vector和deque滿足這些需求。默認(rèn)情況下,如果沒有為特定的priority_queue類實(shí)例化指定容器類,則使用vector。
    • 需要支持隨機(jī)訪問迭代器,以便始終在內(nèi)部保持堆結(jié)構(gòu)。容器適配器通過在需要時自動調(diào)用算法函數(shù)make_heap、push_heap和pop_heap來自動完成此操作
    • 2.priority_queue的使用
    • 優(yōu)先級隊列默認(rèn)使用vector作為其底層存儲數(shù)據(jù)的容器,在vector上又使用了堆算法將vector中元素構(gòu)造成堆的結(jié)構(gòu),因此priority_queue就是堆
    • 所有需要用到堆的位置,都可以考慮使用priority_queue。注意:默認(rèn)情況下priority_queue是大堆

    處理內(nèi)置類型的情況:

    #include <vector> #include <queue> #include <functional> // greater算法的頭文件void TestPriorityQueue() {// 默認(rèn)情況下,創(chuàng)建的是大堆,其底層按照小于號比較vector<int> v{3,2,7,6,0,4,1,9,8,5};priority_queue<int> q1;for (auto& e : v)q1.push(e);cout << q1.top() << endl;// 如果要創(chuàng)建小堆,將第三個模板參數(shù)換成greater比較方式priority_queue<int, vector<int>, greater<int>> q2(v.begin(), v.end());cout << q2.top() << endl; }
    • 如果在priority_queue中放自定義類型的數(shù)據(jù),用戶需要在自定義類型中提供> 或者< 的重載
    class Date { public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}bool operator<(const Date& d)const{return (_year < d._year) ||(_year == d._year && _month < d._month) ||(_year == d._year && _month == d._month && _day < d._day);}bool operator>(const Date& d)const{return (_year > d._year) ||(_year == d._year && _month > d._month) ||(_year == d._year && _month == d._month && _day > d._day);}friend ostream& operator<<(ostream& _cout, const Date& d){_cout << d._year << "-" << d._month << "-" << d._day;return _cout;} private:int _year;int _month;int _day; };void TestPriorityQueue() {// 大堆,需要用戶在自定義類型中提供<的重載priority_queue<Date> q1;q1.push(Date(2018, 10, 29));q1.push(Date(2018, 10, 28));q1.push(Date(2018, 10, 30));cout << q1.top() << endl;// 如果要創(chuàng)建小堆,需要用戶提供>的重載priority_queue<Date, vector<Date>, greater<Date>> q2;q2.push(Date(2018, 10, 29));q2.push(Date(2018, 10, 28));q2.push(Date(2018, 10, 30));cout << q2.top() << endl; }
    • 有些情況下,用戶可能需要提供比較器規(guī)則
    class Less { public:bool operator()(const Date* pLeft, const Date* pRight){return *pLeft < *pRight;} };void TestPriorityQueue() {// 自己定制比較的規(guī)則priority_queue<Date*, vector<Date*>, Less> q;q.push(&Date(2018, 10, 29));q.push(&Date(2018, 10, 28));q.push(&Date(2018, 10, 30));cout << *q.top() << endl;return 0; }
    • priority_queue的模擬實(shí)現(xiàn)
    namespace wolf {template <class T, class Sequence = vector<T>, class Compare = less<T> >class priority_queue{public:priority_queue() : c(){}template <class InputIterator>priority_queue(InputIterator first, InputIterator last): c(first, last){make_heap(c.begin(), c.end(), comp);}bool empty() const { return c.empty(); }size_t size() const { return c.size(); }T& top() const { return c.front(); }void push(const T& x){c.push_back(x);push_heap(c.begin(), c.end(), comp);}void pop(){pop_heap(c.begin(), c.end(), comp);c.pop_back();}private: Sequence c;Compare comp;};}

    五、相關(guān)注意事項

    • 1.為什么使用deque作為stack和queue的底層結(jié)構(gòu)?

    • 首先deque的優(yōu)點(diǎn)是頭部和尾部操作方便,效率可以達(dá)到O(1),缺點(diǎn)是因為deque的底層空間是不連續(xù)的,之所以看起來是連續(xù)的都是迭代器的功勞

    • 正是因為deque的空間不連續(xù),所以對其遍歷的效率極低,因為要判斷尋找下一段空間的位置。

    • 而stack和queue是作為容器適配器來使用的,其不需要遍歷,只需要在兩端進(jìn)行操作即可,剛好避開deque的缺陷。

    • 雖然其他容器也可以作為stack和queue的底層結(jié)構(gòu),但效率都沒有deque高

    • 2.什么是容器適配器?

    • 適配器是一種設(shè)計模式(設(shè)計模式是一套被反復(fù)使用的、多數(shù)人知曉的、經(jīng)過分類編目的、代碼設(shè)計經(jīng)驗的總 結(jié)),該中模式是將一個類的接口轉(zhuǎn)換成客戶希望的另外一個接口

    • 3.為什么將stack、queue和priority_queue稱作為容器適配器?

    • 雖然stack、queue、priority_queue中也可以存放元素,但在STL中并沒有將其劃分在容器的行列,而是將其稱為容器適配器,這是因為每個容器在底層都有自己的實(shí)現(xiàn)方式,而stack、queue、priority_queue只是在底層將其他容器進(jìn)行了封裝

    總結(jié)

    以上是生活随笔為你收集整理的C++中的deque、stack、queue及priority_queue的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。