C++ STL stack queue

目錄

一.stack 介紹

?二.stack 使用

三.stack 模擬實現

普通版本:

適配器版本:

四.queue的介紹

五. queue使用

六.queue模擬實現

七.deque介紹

1.容器適配器

2.deque的簡單介紹

3.deque的缺陷

4.為什么選擇deque作為stack和queue的底層默認容器


一.stack 介紹

stack------reference

1. stack是一種容器適配器,專門用在具有后進先出操作的上下文環境中,其刪除只能從容器的一端進行元素的插入與提取操作。
2. stack是作為容器適配器被實現的,容器適配器即是對特定類封裝作為其底層的容器,并提供一組特定的成員函數來訪問其元素,將特定類作為其底層的,元素特定容器的尾部(即棧頂)被壓入和彈出。
3. stack的底層容器可以是任何標準的容器類模板或者一些其他特定的容器類,這些容器類應該支持以下操作:

  • empty:判空操作
  • back:獲取尾部元素操作
  • push_back:尾部插入元素操作
  • pop_back:尾部刪除元素操作

4. 標準容器vector、deque、list均符合這些需求,默認情況下,如果沒有為stack指定特定的底層容器,默認情況下使用deque。

?二.stack 使用

函數說明接口說明
stack()構造空的棧
empty()檢測stack是否為空
size()返回stack中元素的個數
top()返回棧頂元素的引用
push()將元素val壓入stack中
pop()將stack中尾部的元素彈出

三.stack 模擬實現

普通版本:

stack的模擬實現非常簡單,我們利用已經學過的vector去封裝他的幾個接口就可以了。

	template<class T>class Stack{public:Stack(){}const T& top(){return _v.back();}void pop(){return _v.pop_back();}void push(const T& val){_v.push_back(val);}size_t size(){return _v.size();}bool empty(){return _v.empty();}private:vector<T> _v;};int main(){Stack<int> st;st.push(100);st.push(200);st.push(300);st.push(400);while (!st.empty()){cout << st.top()<<" ";st.pop();}return 0;}

?這里我們使用的是vector做的底層容器,在std::stack中,底層容器是deque并且支持切換成其他容器,這也就是stack被叫做容器適配器的原因。

適配器版本:

容器適配器,我們僅僅需要利用一個類模板參數就可以了,一個類模板參數就可以控制底層存儲數據的容器類型,是vector還是list又或者是deque。

    //容器適配器class Container = vector<T>,class Container = list<T>....template<class T ,class Container >class Stack{public:Stack(){}const T& top(){return _v.back();}void pop(){return _v.pop_back();}void push(const T& val){_v.push_back(val);}size_t size(){return _v.size();}bool empty(){return _v.empty();}private:Container _v;};int main(){Stack<int,list<int>> st;st.push(100);st.push(200);st.push(300);st.push(400);while (!st.empty()){cout << st.top()<<" ";st.pop();}return 0;}

在類模板的哪里也是可以給缺省參數,就可以實現默認存儲容器。

template<class T ,class Container = deque<T>>

四.queue的介紹

queue-----reference

1. 隊列是一種容器適配器,專門用于在FIFO上下文(先進先出)中操作,其中從容器一端插入元素,另一端提取元素。
2. 隊列作為容器適配器實現,容器適配器即將特定容器類封裝作為其底層容器類,queue提供一組特定的成員函數來訪問其元素。元素從隊尾入隊列,從隊頭出隊列。
3. 底層容器可以是標準容器類模板之一,也可以是其他專門設計的容器類。該底層容器應至少支持以下操作:

  • empty:檢測隊列是否為空
  • size:返回隊列中有效元素的個數
  • front:返回隊頭元素的引用
  • back:返回隊尾元素的引用
  • push_back:在隊列尾部入隊列
  • pop_front:在隊列頭部出隊列

4. 標準容器類deque和list滿足了這些要求。默認情況下,如果沒有為queue實例化指定容器類,則使用標準容器deque。?

五. queue使用

函數聲明接口說明
queue()構造空的隊列
empty()檢測隊列是否為空,是返回true,否則返回false
size()返回隊列中有效元素的個數
front()返回隊頭元素的引用
back()返回隊尾元素的引用
push()在隊尾將元素val入隊列
pop()將隊頭元素出隊列

六.queue模擬實現

因為queue的接口中存在頭刪和尾插,因此使用vector來封裝效率太低,故可以借助list來模擬實現queue,具體如下:

普通list版本:

    template<class T>class Queue{public:Queue(){}void push(const T& val){_q.push_back(val);}void pop(){_q.pop_front();}const T& front(){return _q.front();}const T& back(){return _q.back();}size_t size(){return _q.size();}bool empty(){return _q.empty();}private:list<T> _q;};

適配器版本:

    template<class T,class Container=list<T>>class Queue{public:Queue(){}void push(const T& val){_q.push_back(val);}void pop(){_q.pop_front();}const T& front(){return _q.front();}const T& back(){return _q.back();}size_t size(){return _q.size();}bool empty(){return _q.empty();}private:Container _q;};

?七.deque介紹

1.容器適配器

適配器是一種設計模式(設計模式是一套被反復使用的、多數人知曉的、經過分類編目的、代碼設計經驗的總結),該種模式是將一個類的接口轉換成客戶希望的另外一個接口。

STL標準庫中stack和queue的底層結構 :

雖然stack和queue中也可以存放元素,但在STL中并沒有將其劃分在容器的行列,而是將其稱為容器適配器,這是因為stack和隊列只是對其他容器的接口進行了包裝,STL中stack和queue默認使用deque,比如:

2.deque的簡單介紹

deque(雙端隊列):是一種雙開口的"連續"空間的數據結構,雙開口的含義是:可以在頭尾兩端進行插入和刪除操作,且時間復雜度為O(1),與vector比較,頭插效率高,不需要搬移元素;與list比較,空間利用率比較高。

?同時從庫中提供的接口來看,deque還提供了下標的隨機訪問的功能,但是deque并不是真正連續的空間,而是由一段段連續的小空間拼接而成的,實際deque類似于一個動態的二維數組,其底層結構如下圖所示:

?雙端隊列底層是一段假象的連續空間,實際是分段連續的,為了維護其“整體連續”以及隨機訪問的假象,落在了deque的迭代器身上,因此deque的迭代器設計就比較復雜,如下圖所示:

? 3.deque的缺陷

與vector比較,deque的優勢是:頭部插入和刪除時,不需要搬移元素,效率特別高,而且在擴容時,也不需要搬移大量的元素,因此其效率是比vector高的。與list比較,其底層是連續空間,空間利用率比較高,不需要存儲額外字段。
但是,deque有一個致命缺陷:不適合遍歷,因為在遍歷時,deque的迭代器要頻繁的去檢測其是否移動到某段小空間的邊界,導致效率低下,而序列式場景中,可能需要經常遍歷,因此在實際中,需要線性結構時,大多數情況下優先考慮vector和list,deque的應用并不多,而目前能看到的一個應用就是,STL用其作為stack和queue的底層數據結構。

4.為什么選擇deque作為stack和queue的底層默認容器

stack是一種后進先出的特殊線性數據結構,因此只要具有push_back()和pop_back()操作的線性結構,都可以作為stack的底層容器,比如vector和list都可以;queue是先進先出的特殊線性數據結構,只要具有push_back和pop_front操作的線性結構,都可以作為queue的底層容器,比如list。但是STL中對stack和queue默認選擇deque作為其底層容器,主要是因為:

  1. ?stack和queue不需要遍歷(因此stack和queue沒有迭代器),只需要在固定的一端或者兩端進行操作。
  2. 在stack中元素增長時,deque比vector的效率高(擴容時不需要搬移大量數據);queue中的元素增長時,deque不僅效率高,而且內存使用率高。

結合了deque的優點,而完美的避開了其缺陷。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/40420.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/40420.shtml
英文地址,請注明出處:http://en.pswp.cn/news/40420.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

System.Text.Encoding不同字符編碼之間進行轉換

System.Text.Encoding 是 C# 中用于處理字符編碼和字符串與字節之間轉換的類。它提供了各種靜態方法和屬性&#xff0c;用于在不同字符編碼之間進行轉換&#xff0c;以及將字符串轉換為字節數組或反之。 在處理多語言文本、文件、網絡通信以及其他字符數據的場景中&#xff0c…

Spring Boot 獲取前端參數

Spring Boot 獲取前端參數 在開發 Web 應用程序時&#xff0c;前端參數是非常重要的。Spring Boot 提供了多種方法來獲取前端參數&#xff0c;本文將介紹其中的一些常用方法。 1. 使用 RequestParam 注解 RequestParam 注解是 Spring MVC 提供的一種常用方式&#xff0c;用于…

C++ 函數

函數是一組一起執行一個任務的語句。每個 C 程序都至少有一個函數&#xff0c;即主函數 main() &#xff0c;所有簡單的程序都可以定義其他額外的函數。 您可以把代碼劃分到不同的函數中。如何劃分代碼到不同的函數中是由您來決定的&#xff0c;但在邏輯上&#xff0c;劃分通常…

pycharm調整最大堆發揮最大

python程序運行時&#xff0c;怎么提高效率&#xff0c;設置pycharm最大堆過程如下&#xff1b; 一、進入設置pycharm最大堆&#xff1b; 二、進入設置pycharm最大堆&#xff1b; 如果8g設置為6g左右&#xff0c;占75%左右最佳

5個實用的 Vue 技巧

在這篇文章中&#xff0c;我們將探討五個實用的 Vue 技巧&#xff0c;這些技巧可以使你日常使用 Vue 編程更高效、更富有成效。無論你是Vue的初學者還是經驗豐富的開發者&#xff0c;這些技巧都能幫助你編寫更清晰、更簡潔、更有效的代碼。那么&#xff0c;讓我們開始吧。 1. …

9.1 C++ STL 排序、算數與集合

C STL&#xff08;Standard Template Library&#xff09;是C標準庫中的一個重要組成部分&#xff0c;提供了豐富的模板函數和容器&#xff0c;用于處理各種數據結構和算法。在STL中&#xff0c;排序、算數和集合算法是常用的功能&#xff0c;可以幫助我們對數據進行排序、統計…

【JVM】JVM中的分代回收

文章目錄 分代收集算法什么是分代分代收集算法-工作機制MinorGC、 Mixed GC 、 FullGC的區別是什么 分代收集算法 什么是分代 在java8時&#xff0c;堆被分為了兩份&#xff1a; 新生代和老年代【1&#xff1a;2】 其中&#xff1a; 對于新生代&#xff0c;內部又被分為了三…

eclipse常用設置

1、調整編輯頁面字體大小 窗口 (Window)- 首選項&#xff08;Preferences&#xff09;- 常規&#xff08;General&#xff09;- 外觀 (Appearence)- 顏色與字體 (Colors And Fonts)&#xff0c;在右邊的對話框里選擇 Java - Java Editor Text Font&#xff0c;點擊出現的修改&…

【ARM 嵌入式 編譯系列 3.3 -- gcc 動態庫與靜態庫的鏈接方法介紹】

文章目錄 1.1 GCC 鏈接器 LD 介紹1.1.1 GCC 鏈接器 LD 常用參數介紹1.2 動態庫和靜態庫介紹1.2.1 動態庫和靜態庫優缺點1.2.2 庫文件鏈接方式1.2.3 ldd 工具介紹1.2.4 靜態庫鏈接時搜索路徑順序1.2.5 動態庫鏈接時、執行時搜索路徑順序1.2.6 頭文件搜索路徑1.2.7 有關環境變量上…

Neo4j之Aggregation基礎

在 Neo4j 中&#xff0c;聚合&#xff08;Aggregation&#xff09;是對數據進行計算、匯總和統計的過程。以下是一些使用聚合函數的常見例子&#xff0c;以及它們的解釋&#xff1a; 計算節點數量&#xff1a; MATCH (p:Person) RETURN count(p) AS totalPersons;這個查詢會計…

Socks5代理在多線程爬蟲中的應用

在進行爬蟲開發過程中&#xff0c;我們常常需要處理大量的數據&#xff0c;并執行多任務并發操作。然而&#xff0c;頻繁的請求可能會引起目標網站的反爬機制&#xff0c;導致IP封禁或限制訪問。為了規避這些限制&#xff0c;我們可以借助Socks5代理的強大功能&#xff0c;通過…

Nginx反向代理技巧

跨域 作為一個前端開發者來說不可避免的問題就是跨域&#xff0c;那什么是跨域呢&#xff1f; 跨域&#xff1a;指的是瀏覽器不能執行其他網站的腳本。它是由瀏覽器的同源策略造成的&#xff0c;是瀏覽器對javascript施加的安全限制。瀏覽器的同源策略是指協議&#xff0c;域名…

2011-2021年數字普惠金融指數Bartik工具變量法(含原始數據和Bartik工具變量法代碼)

2011-2021年數字普惠金融指數Bartik工具變量法&#xff08;含原始數據和Bartik工具變量法代碼&#xff09; 1、時間&#xff1a;2011-2020&#xff08;省級、城市&#xff09;&#xff0c;2014-2020&#xff08;區縣&#xff09; 2、原始數據來源&#xff1a;北大金融研究中心…

npm的鏡像源和代理的查看和修改

一、鏡像源 查詢當前鏡像源 npm get registry 設置為淘寶鏡像 npm config set registry http://registry.npm.taobao.org/ 設置回默認的官方鏡像 npm config set registry https://registry.npmjs.org/ 設置electron為淘寶鏡像 npm config set ELECTRON_MIRROR "h…

Redis對象類型和結構、內存回收、對象共享

對象類型和結構 在Redis中&#xff0c;無論是鍵key還是值value都是一個對象&#xff0c;每次對Redis數據庫創建一個新的鍵值對時&#xff0c;就至少會創建兩個對象。 常見的對象類型有&#xff1a; 字符串列表哈希集合有序集合 這些對象在Redis中統一用一個結構體redisObjec…

VS2019生成的DLL,給QT(MinGW版本)使用的小結

VS2019端&#xff1a; a 基于生成一個DLL的工程&#xff08;要注意生成是x86&#xff0c;還是x64的&#xff0c;需要和后面的QT的App工程對應&#xff09;&#xff0c;這里不多解釋了&#xff0c;網上多的是&#xff1b; b 在cpp實現文件里&#xff0c;假如要導出一個這樣的…

Git如何上傳文件到github

Git下載網址&#xff1a; https://git-scm.com/downloads 1. 新建一個空文件夾&#xff0c;用來上傳文件&#xff0c;第一次需創建&#xff0c;以后無需創建 2. 點進去空文件夾&#xff0c;鼠標右鍵&#xff0c;使用Git Bash Here 打開 3. 克隆遠程倉庫&#xff1a;git cl…

深入理解JVM——垃圾回收與內存分配機制詳細講解

所謂垃圾回收&#xff0c;也就是要回收已經“死了”的對象。 那我們如何判斷哪些對象“存活”&#xff0c;哪些已經“死去”呢&#xff1f; 一、判斷對象已死 1、引用計數算法 給對象中添加一個引用計數器&#xff0c;每當有一個地方引用它時&#xff0c;計數器就加一&…

解決git reset --soft HEAD^撤銷commit時報錯

今天在使用git回退功能的時候&#xff0c;遇到以下錯誤&#xff1a; 解決git reset --soft HEAD^撤銷commit時報錯 問題&#xff1a; 在進行完commit后&#xff0c;想要撤銷該commit&#xff0c;于是使用了git reset --soft HEAD^命令&#xff0c;但是出現如下報錯&#xff1…

【學習心得】安裝cuda/cudann和pytorch

一、查看驅動信息 # 進入CMD輸入命令 nvidia-smi 也可以右下角圖標打開NVIDIA 設置進行查看 二、下載安裝CUDA 1、下載 下載地址 https://developer.nvidia.com/ 2、安裝 推薦自定義安裝。建議只勾選Cuda&#xff0c;只安裝這一個就好&#xff0c;以免報錯安裝失敗。 3、驗證…