stack和queue簡單模擬實現

  • stack
  • reverse_iterator
  • queue
  • priority_queue
    • 仿函數
    • 具體代碼

stack

Stacks are a type of container adaptor, specifically designed to operate in a LIFO context (last-in first-out), where elements are inserted and extracted only from one end of the container.

上述描述出自cplusplus.

重點是stack是一個container adaptor也就是容器適配器。
這意味著我們不需要也沒有必要從0開始實現stack的方法,而可以通過一個模板,來調用其他容器來實現,以下是stack的部分從成員函數:

template<class T, class Container = deque<int>>
class stack
{
public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_back();}size_t size(){return _con.size();}bool empty(){return _con.empty();}const T& top(){return _con.back();}private:Container _con;
};

可以發現只需要調用傳來的模板參數即可。

這里的默認容器是deque,這是一個均衡的容器,整體效率沒有vector高,但是可以實現push_front。這是vector做不到的,或者說vector的頭插效率是O(n),過低。

值得注意的是,所有容器適配器都不支持迭代器
就以stack舉例,如果支持迭代器,那是否意味著破壞了他的FILO特性呢?是的。因此不支持迭代器。

reverse_iterator

上文提到容器適配器,那就不得不提到反向迭代器了。
之前我們實現vector和list的時候都沒有實現反向迭代器,因為兩者內容過于相似,現在了解了反向迭代器的機制后我們知道,是否可以通過穿入迭代器容器,然后實現反向迭代器。

這意味著,我們可以同時實現所有容器的反向迭代器,也就是實現他們的模板:

template<class Iterator,class Ref,class Ptr>
struct Reverse_iterator
{typedef Reverse_iterator<Iterator, Ref, Ptr> Self;Iterator _it;Reverse_iterator(Iterator it):_it(it){}Ref operator*(){Iterator tmp = _it;return *((--tmp));}Ptr operator->(){return &(operator*());}Self& operator++(){return --_it;}Self& operator--(){return ++_it;}bool operator!=(const Self& it){return _it != it;}};

需要注意的一點是,我們的operator*返回的是 *(--tmp),而不是 *(tmp).

原因是,我們的rbegin()和rend()返回的是end()和begin()。這是基于代碼對稱性考慮的,正常而言我們的rbegin()和rend()理應返回end()-1和begin()-1.

為了解決這個問題,就只能令operator*返回 *(--tmp)

注:以上實現是visual studio的實現方式。

queue

template<class T, class Container = deque<int>>
class queue
{
public:void push(const T& x){_con.push_back(x);}void pop(){_con.pop_front();}size_t size(){return _con.size();}bool empty(){return _con.empty();}const T& front(){return _con.front();}const T& back(){return _con.back();}private:Container _con;
};

priority_queue

priority_queue實質上就是一個堆,并且是默認大根堆。那么我們想要將其改變為小根堆改如何實現?
如果是C語言的話,我們會增加一個函數指針的參數來實現。
在C++中,我們通過傳入一個仿函數來實現。

仿函數

所謂仿函數就是指能夠像函數一樣使用的對象,如下:

template<class T>
class less
{
public:bool operator()(const T& x, const T& y){return x < y;}
};
void test(int x,int y)
{less l;if(l(x,y))cout<<"x<y";else cout<<"x>=y";
}

本質上,我們重載了 (),因此能夠將這個對象像函數一樣使用。

具體代碼

堆的實現,我們已經講過,這里就不做贅述,感興趣的讀者可以翻閱我前面的文章。

template<class T,class Container=vector<T>,class Compare = less<T>>
class priority_queue
{
public://默認大堆void adjust_up(size_t child){size_t parent = (child - 1) / 2;Compare com;while (child >0){if (com(_con[parent], _con[child])){std::swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}void push(const T& x){_con.push_back(x);adjust_up(_con.size() - 1);}void adjust_down(size_t parent){size_t child = parent * 2 + 1;while (child<_con.size()){if (child + 1 < _con.size() && com(_con[child],_con[child+1])){++child;}if (com(_con[parent],_con[child])){std::swap(_con[child], _con[parent]);parent = child;child = parent * 2 + 1;}else{break;}}}void pop(){std::swap(_con[0], _con[_con.size() - 1]);_con.pop_back();adjust_down(0);}bool empty(){return _con.empty();}size_t size(){return _con.size();}const T& top(){return _con[0];}private:Container _con;
};

說起來這里比較奇怪的點是,默認傳入less<T>是大根堆,而穿入greater<T>卻是小根堆。
但sort穿入,less<T>卻是升序排序:

int main()
{vector<int>v = { 1,5,4,3,2 };sort(v.begin(), v.end(),less<int>());//傳入less的匿名對象for (auto& e : v)cout << e << ' ';cout << endl;return 0;
}

Output:1 2 3 4 5

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

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

相關文章

Linux內核可配置的參數

sysctl -a 命令會列出當前Linux內核所有可配置的參數及其當前值。這些參數允許你在系統運行時動態地調整內核的行為&#xff0c;而無需重新編譯內核或重啟系統。 內容非常多&#xff0c;因為內核有很多可調的方面。我們可以把它們大致分為幾個主要類別&#xff1a; kernel.*: …

【背包dp-----分組背包】------(標準的分組背包【可以不裝滿的 最大價值】)

通天之分組背包 題目鏈接 題目描述 自 01 01 01 背包問世之后&#xff0c;小 A 對此深感興趣。一天&#xff0c;小 A 去遠游&#xff0c;卻發現他的背包不同于 01 01 01 背包&#xff0c;他的物品大致可分為 k k k 組&#xff0c;每組中的物品相互沖突&#xff0c;現在&a…

操作系統:os概述

操作系統&#xff1a;OS概述 程序、進程與線程無極二級目錄三級目錄 程序、進程與線程 指令執行需要那些條件&#xff1f;CPU內存 需要數據和 無極 二級目錄 三級目錄

RAG文本分塊

不論是向量化模型還是大語言模型&#xff0c;都存在輸入長度的限制。對于超過限制的文本&#xff0c;模型會進行截斷&#xff0c;造成語義缺失。分塊可以確保每個文本片段都在模型的處理范圍內&#xff0c;避免重要信息的丟失。 文本分塊的核心原則 高質量分塊的核心原則是&a…

2025 年九江市第二十三屆中職學校技能大賽 (網絡安全)賽項競賽樣題

2025 年九江市第二十三屆中職學校技能大賽 &#xff08;網絡安全&#xff09;賽項競賽樣題 &#xff08;二&#xff09;A 模塊基礎設施設置/安全加固&#xff08;200 分&#xff09;A-1 任務一登錄安全加固&#xff08;Windows,Linux&#xff09;A-2 任務二 Nginx 安全策略&…

量子隧穿:PROFINET到Ethernet ip的無損耗協議轉換方案轉

在本季度的生產工作中&#xff0c;我們成功實現了倉儲物流自動化分揀系統中的關鍵技術突破。我們面臨的主要挑戰是將采用EtherNet/IP協議的輸送帶控制器與PROFINET協議的上位系統進行有效通信。通過引入ethernet IP轉PROFINET網關倍訊科技BX-606-EIP&#xff0c;我們實現了輸送…

OpenCV CUDA模塊中矩陣操作------降維操作

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 cv::cuda::reduce 函數用于對 GPU 上的矩陣沿某個維度進行降維操作&#xff0c;例如求和、取最大值等。此函數支持多種降維操作&#xff0c;并允…

一分鐘用 MCP 上線一個 貪吃蛇 小游戲(CodeBuddy版)

我正在參加CodeBuddy「首席試玩官」內容創作大賽&#xff0c;本文所使用的 CodeBuddy 免費下載鏈接&#xff1a;騰訊云代碼助手 CodeBuddy - AI 時代的智能編程伙伴 你好&#xff0c;我是悟空。 背景 上篇我們用 MCP 上線了一個 2048 小游戲&#xff0c;這次我們繼續做一個 …

簡單神經網絡(ANN)實現:從零開始構建第一個模型

本文將手把手帶你用 Python Numpy 實現一個最基礎的人工神經網絡&#xff08;Artificial Neural Network, ANN&#xff09;。不依賴任何深度學習框架&#xff0c;適合入門理解神經網絡的本質。 一、項目目標 構建一個三層神經網絡&#xff08;輸入層、隱藏層、輸出層&#xf…

使用python進行人員軌跡跟蹤

一、系統概述 該系統基于計算機視覺技術&#xff0c;實現對視頻或攝像頭畫面中的人員進行檢測、跟蹤&#xff0c;并生成軌跡數據。支持透視變換校準&#xff08;鳥瞰圖顯示&#xff09;、多目標跟蹤、軌跡存儲及視頻錄制功能&#xff0c;適用于安防監控、行為分析等場景。 二…

[強化學習的數學原理—趙世鈺老師]學習筆記02-貝爾曼方程

本人為強化學習小白&#xff0c;為了在后續科研的過程中能夠較好的結合強化學習來做相關研究&#xff0c;特意買了西湖大學趙世鈺老師撰寫的《強化學習數學原理》中文版這本書&#xff0c;并結合趙老師的講解視頻來學習和更深刻的理解強化學習相關概念&#xff0c;知識和算法技…

Docker入門指南:鏡像、容器與倉庫的核心概念解析

目錄 前言&#xff1a;為什么需要Docker&#xff1f; 一、Docker能做什么&#xff1f; 二、核心概念解析 1. 鏡像&#xff08;Image&#xff09;&#xff1a;應用的標準化打包 2. 容器&#xff08;Container&#xff09;&#xff1a;鏡像的運行實例 3. 鏡像倉庫&#xff0…

大模型微調實戰:基于GpuGeek平臺的低成本高效訓練方案

文章目錄 引言一、GpuGeek平臺使用入門1. 注冊與賬號設置2. 控制臺功能概覽3. 快速創建GPU實例3. 預置鏡像與自定義環境 二、GpuGeek平臺核心優勢解析1. 顯卡資源充足&#xff1a;多卡并行加速訓練2. 鏡像超多&#xff1a;開箱即用的開發環境3. 計費靈活&#xff1a;按需付費降…

Linux:計算機的層狀結構

1.馮諾依曼體系結構 我們常見的計算機&#xff0c;如筆記本、臺式機。我們不常見的計算機&#xff0c;如服務器&#xff0c;大部分都遵守馮諾依曼體系結構。 CPU&#xff1a;運算器和控制器組成。運算器主要工作是做算術運算和邏輯運算。控制器主要工作是協調設備之間信息流動的…

LangGraph(四)——加入人機交互控制

目錄 1. 引言2. 添加Human Assistance工具3. 編譯狀態圖4. 提示聊天機器人5. 恢復執行參考 1. 引言 智能體可能不可靠&#xff0c;甚至需要人工輸入才能完成任務。同樣&#xff0c;對于某些操作&#xff0c;你可能需要在運行前獲得人工批準&#xff0c;以保證一切按預期運行。 …

數據結構【AVL樹】

AVL樹 1.AVL樹1.AVL的概念2.平衡因子 2.AVl樹的實現2.1AVL樹的結構2.2AVL樹的插入2.3 旋轉2.3.1 旋轉的原則 1.AVL樹 1.AVL的概念 AVL樹可以是一個空樹。 它的左右子樹都是AVL樹&#xff0c;且左右子樹的高度差的絕對值不超過1。AVL樹是一顆高度平衡搜索二叉樹&#xff0c;通…

JavaScript【5】DOM模型

1.概述&#xff1a; DOM (Document Object Model)&#xff1a;當頁面被加載時&#xff0c;瀏覽器會創建頁面的文檔對象模型&#xff0c;即dom對象&#xff1b;dom對象會被結構化為對象樹&#xff0c;如一個HTML文檔會被分為head&#xff0c;body等部分&#xff0c;而每個部分又…

STM32燒錄程序正常,但是運行異常

一、硬件配置問題 BOOT引腳設置錯誤 STM32的啟動模式由BOOT0和BOOT1引腳決定。若設置為從RAM啟動&#xff08;BOOT01&#xff0c;BOOT10&#xff09;&#xff0c;程序在掉電后無法保存&#xff0c;導致復位后無法正常運行。應確保BOOT00&#xff08;從Flash啟動&#xff09;15。…

汽車二自由度系統模型以及電動助力轉向系統模型

汽車二自由度系統模型與電動助力轉向系統&#xff08;EPS&#xff09;的詳細建模方案&#xff0c;包含理論推導、MATLAB/Simulink實現代碼及參數說明&#xff1a; 一、二自由度汽車模型 1. 模型描述 包含以下兩個自由度&#xff1a; 橫向運動&#xff08;側向加速度&#xf…

git提交庫常用詞

新功能 feat修改BUG fix文檔修改 docs格式修改 style重構 refactor性能提升 perf測試 test構建系統 build對CI配置文件修改 ci修改構建流程、或增加依賴庫、工具 chore回滾版本 revert