stack、queue、priority_queue以及仿函數

我們上次對std中的list進行實現,今天我們要實現stack、queue、priority_queue以及仿函數。

目錄

  • stack堆
    • 堆的框架
    • 構造函數
    • push插入
    • pop刪除
    • size()大小
    • empty()判斷空
    • top()取棧頂的元素
  • queue隊列
    • 隊列框架
      • 問題: 這里我們為什么用deque?
    • 插入
    • 刪除
    • 取頭數據
    • 取尾數據
    • 判斷空和大小
  • priority_queue堆
    • priority_queue的架構
      • empty()判斷空
      • size()大小
      • top()取堆頂元素
      • sawp()交換
      • push()插入
      • pop()刪除
    • 仿函數
      • 仿函數架構

stack堆

堆的原則就是先進后出,后進先出。如圖:
在這里插入圖片描述

從上圖我們可以看出來stack準確說就是一個vector,所以我們就可以利用vector來建。

堆的框架

既然是實現STL庫,一定是相似與庫中,我們先不看他用的是誰,我們剛剛也分析了用vector來實現,所以我們可以用vector來封裝。
在這里插入圖片描述
這里的Con表示Container(容器),我們只需要傳一個容器類型就可以,這里用vector是因為stack的特性,也可以用deque(他是鏈表與順序表的結合,這里不會多說)。

    template<class T, class Con = vector<T>>class stack{public:private:Con _c;};

構造函數

沒錯,你沒看錯,這里我們的構造函數什么都沒有寫,其實你不寫構造函數也可以,我們也說了構造函數對內置類型不做處理,但是對內置類型會去調用它的默認構造,這里我們用了container容器,我們傳什么容器類型就是什么容器,我們就可以間接區調用它的構造函數

stack()
{}

push插入

push其實很簡單,vector中插入數據是不是用的push_back();那么我們可以調用那個成員函數,來達到插入效果。
在這里插入圖片描述

 void push(const T& x){_c.push_back(x);}

pop刪除

pop也是一樣的。復用接口。因為我們是后進的先出,所以我們就尾刪。

       void pop(){_c.pop_back();}

size()大小

 size_t size()const{return _c.size();}

empty()判斷空

bool empty()const
{return  _c.empty();
}

top()取棧頂的元素

那么什么是棧頂呢?如果數據1的位置是0,那么數據3的位置一定是n-1,所以我們有了size就可以,用size()-1;而且vector支持下標。
在這里插入圖片描述

  T& top(){return _c[size() - 1];}

queue隊列

隊列的特性是先進先出,后進后出
在這里插入圖片描述

隊列框架

其實隊列和棧的框架是一樣的。

template<class T, class Con = deque<T>>class queue{public:private:Con _c;};

問題: 這里我們為什么用deque?

因為頭刪問題,我們也知道頭刪vector是效率很低的,你會說為什么不用list,list不支持下標訪問,但是這里用deque就能很好的避免,因為庫中deque既有頭刪,也可以下標訪問
在這里插入圖片描述

deque的結構其實就是鏈表和vector的結合。但是deque的缺點也很致命。

  • deque的優點
    ①.頭插尾插很快,不需要挪數據,只需要開空間插入
    ②支持連續訪問
  • deque的缺點
    ①.中間的插入刪除效率麻煩且一般。
    ②.方括號的效率并不極致。

插入

void push(const T& x)
{_c.push_back(x);
}

刪除

void pop()
{_c.pop_front();
}

取頭數據

 T& front(){return _c.front();}const T& front()const{return _c.front();}

取尾數據

        T& back(){return _c.back();}const T& back()const{return _c.back();}

判斷空和大小

  size_t size()const{return   _c.size();}bool empty()const{return  _c.empty();}

priority_queue堆

優先級隊列和隊列沒有任何關系!優先級隊列是堆,并且他默認是大堆!我們看庫中會發現,他和queue共用一個頭文件。
在這里插入圖片描述

我們在看一下庫中的實現。有模板參數有 T、Container、那么Compare是啥啊?我們先不管,看庫的時候,遇到不懂得,我們可以先往下看看,如果不影響我們就先不看他,所以我們先排除Compare。先把架子搭出來。
在這里插入圖片描述

priority_queue的架構

我們還是復用容器類型,堆是完全二叉樹,并且之前我們用vector就可以,通過上下調整位置,達到堆。

template<class T ,class Container=vector<T>, class Compare = less<T> >
class priority_queue
{
public:private:Container _con;
};

在這里插入圖片描述

empty()判斷空

我們從上圖可以看出來priority_queue的成員函數并不多。

bool empty() const
{return _con.empty();
}	

size()大小

size_t size() const
{return _con.size();
}

top()取堆頂元素

堆頂元素是誰?是不是root根啊,我們用的也是vector,所以堆頂很好取。

T& top() 
{return _con[0];
}

sawp()交換

	void swap(T& p1,T&p2){std::swap(p1,p2);}

push()插入

我們之前學習堆的時候插入是怎么插入的?插到尾部,然后不斷向上調整。如圖,默認是大堆,我們在尾巴插入一個20,向上調整。通過父子對比,孩子比父親大,我們就向上調整。
在這里插入圖片描述

		void push(const T& x){//尾插然后向上調整_con.push_back(x);AdjustUp(size()-1);}void AdjustUp(int child){//Compare c;int parent = (child - 1) / 2;//找父親while (child > 0){//不斷調整,直到不滿足要求了,結束//if (_con[child] > _con[parent])//if (c(_con[parent], _con[child]))if (_con[parent]<_con[child]){swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}elsebreak;}}

pop()刪除

庫中說從頂部移除元素,所以我們需要刪除堆頂。刪除堆頂元素,我們可以首尾交換,然后尾刪,向下調整
在這里插入圖片描述
如圖:
在這里插入圖片描述

void pop()
{//頭尾交換,刪除,然后向下調整swap(_con[0], _con[size() - 1]);_con.pop_back();AdjustDown(0);
}
void AdjustDown(int parent)
{//Compare c;int child = parent * 2 + 1;while (child < size()){if (child < size() - 1 && _con[child] < _con[child + 1])//if (child < size() - 1 && c(_con[child], _con[child + 1])){//這里需要判斷一下,因為我們找的都是左子樹,判斷一下右子樹是否存在//如果存在,在判斷一下那個大,哪個大就和哪個換。(默認大堆)child++;}if (_con[parent] < _con[child])//if (c(_con[parent], _con[child])){swap(_con[child], _con[parent]);parent = child;child = parent * 2 + 1;}elsebreak;}
}

仿函數

上述我們只能實現默認的大堆,現在如果我希望你實現一個小堆,你怎么辦?ok,你會說我修改一下大于小于號,那么如果在實戰的項目中,讓你實現,你會和客戶說等我一下,我修改一下大于小于號?那不可能,那怎么做呢?仿函數!

其實我們也見過仿函數,在排序中,我們可以利用仿函數排升序降序。
在這里插入圖片描述
如果你在C語言階段用過排序qsort();里面是不是會讓你們傳一個函數指針類型?其實仿函數就是解決了回調函數問題(函數指針)。

仿函數架構

其實在我們上面寫priority_queue的時候,你會發現默認給的less卻是大堆,這個我也不知道為什么,記住就好了。其實仿函數,你可以理解為,只要重載了operator() 就算是仿函數
你看輸出的時候,是不是特別像一個函數?其實并不是的,其實只是重載了小括號。
在這里插入圖片描述

	template<class T>class less{//控制大堆public:bool operator()( const T& x,const T&y){return x < y;}};template<class T>class greater{//控制小堆public:bool operator()(const T& x, const T& y){return x > y;}};template<class T ,class Container=vector<T>, class Compare = less<T> >class priority_queue{public:void push(const T& x){//尾插然后向上調整_con.push_back(x);AdjustUp(size()-1);}void pop(){//頭尾交換,刪除,然后向下調整swap(_con[0], _con[size() - 1]);_con.pop_back();AdjustDown(0);}private:void AdjustDown(int parent){Compare c;int child = parent * 2 + 1;while (child < size()){//if (child < size() - 1 && _con[child] < _con[child + 1])if (child < size() - 1 && c(_con[child], _con[child + 1])){child++;}//if (_con[parent] < _con[child])if (c(_con[parent], _con[child])){swap(_con[child], _con[parent]);parent = child;child = parent * 2 + 1;}elsebreak;}}void AdjustUp(int child){Compare c;//創建比較的對象int parent = (child - 1) / 2;while (child > 0){//if (_con[child] > _con[parent])//if (_con[parent]<_con[child])if (c(_con[parent], _con[child]))//傳哪個仿函數調哪個{swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}elsebreak;}}Container _con;};

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

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

相關文章

AI交互數字人賦能農業數字化、智能化推廣營銷

2024陵水荔枝文化節上“數字新農人”陵小荔身著黎族服飾、佩戴銀器亮相開幕式現場&#xff0c;AI交互數字人生動地以互動式推介和歌舞等形式&#xff0c;帶領賓客們了解陵水荔枝的發展歷程、產業布局、未來愿景等。如今&#xff0c;越來越多農產品品牌通過3D虛擬數字人定制&…

Redis和數據庫能做到強一致嗎?

在現代軟件系統中&#xff0c;數據一致性是至關重要的&#xff0c;特別是對于需要處理大量并發請求和實時數據的系統。Redis 和數據庫都是常見的數據存儲解決方案&#xff0c;但它們在保證數據一致性方面有著不同的特點和限制。 本文將深入探討 Redis 和數據庫是否能夠做到強一…

最詳細的提單知識總結 | 數字貿易綜合服務平臺 | 箱訊科技

在外貿交易中&#xff0c;國際物流是必不可少的一個步驟。國際物流掌控好&#xff0c;就等于把貨物牢牢握在手心&#xff0c;不怕貨財兩空。 本期將向大家介紹正本提單、電放提單、海運單三種國際海運放貨方式以及區分它們的方法。 超實用&#xff01;外貿人趕緊收藏~ 正本提…

CTF例題:[SWPU2019]Web1(無列名注入)

網址&#xff1a;BUUCTF在線評測 搜索web1 啟動靶機 點擊鏈接進入題目 進入題目后發現有登錄和注冊接口&#xff0c;直接注冊登錄。 首先通過1進行測試&#xff0c;查看是否有注入點 出現報錯&#xff0c;說明可能存在注入點 然后繼續測試發現該服務器過濾了&#xff1a; or、…

vue(九) 生命周期 v3.0和v2.0對比,父子組件生命周期的執行順序

文章目錄 生命周期vue2.0生命周期1.圖示2.生命周期解釋說明3.代碼示例 vue3.0生命周期1.圖示2.生命周期解釋說明3.代碼示例 父子組件中生命周期執行順序v.3和v2.0生命周期對比 生命周期 每個 Vue 組件實例在創建時都需要經歷一系列的初始化步驟&#xff0c;比如設置好數據偵聽…

Android 獲取已安裝應用、包名、應用名、版本號、版本名

1、相關代碼 List<ApplicationInfo> installedApps getPackageManager().getInstalledApplications(0);for (ApplicationInfo appInfo : installedApps) {CharSequence getAppName getPackageManager().getApplicationLabel(appInfo);String appNamegetAppName.toStrin…

怎么做私域?先來了解私域運營模式!

現在&#xff0c;很多企業都在做私域&#xff0c;但仍舊有很多人會問&#xff1a;我的私域到底要怎么做&#xff1f; 關于這個問題&#xff0c;不同產品無論在消費頻次與客單價上&#xff0c;還是在決策鏈路的長度和復雜度上&#xff0c;都有巨大的差異&#xff0c;消費者需要…

前端 JS 經典:雙等號運算符的運算和轉換規則

1. 運算規則 兩端存在 NaN&#xff0c;返回 false NaN NaN; // false NaN 1; //false undefined 和 null 只有與自身比較&#xff0c;或者相互比較時&#xff0c;才返回 true&#xff0c;和其他原始類型比較都返回 false。 undefined null; // true undefined undefine…

flutter組件封裝技巧

這段代碼是一個用于創建一個&#xff08;GradeTag&#xff09;組件的類。這個組件可以根據輸入的年級和顏色創建一個具有不同顏色和百分比顯示的標簽。 實現原理&#xff1a; 使用GradeTag.origin構造函數來創建一個包含默認顏色和百分比的字符串。這個構造函數使用了assert來…

如何使用AspectJ做切面,打印jar包中方法的執行日記

最近在工作中遇到一個redis緩存中的hash key莫名其妙被刪除的問題&#xff0c;我們用了J2Cache&#xff0c;二級緩存用的是redis。hash key莫名其妙被刪除又沒有日志&#xff0c;就想到做一個切面在調用redis刪除hash key的方法的時候&#xff0c;打印日志&#xff0c;并且把調…

高德、百度開車導航APP是怎么知道紅綠燈倒計時的?

高德、百度開車導航APP之所以能夠知道紅綠燈的倒計時&#xff0c;這背后是一系列復雜的科技手段和數據分析的綜合運用。從交管部門提供的數據&#xff0c;到導航軟件自身通過大數據和算法進行的計算&#xff0c;每一個環節都為紅綠燈倒計時的準確呈現提供了支撐。 首先&#xf…

白酒:低酒精度白酒的消費特點與市場前景

低酒精度白酒的消費特點與市場前景是酒類市場的一個重要話題。隨著品質意識的提高和消費者口味的多樣化&#xff0c;低酒精度白酒逐漸受到越來越多的關注。云倉酒莊豪邁白酒作為白酒的品牌之一&#xff0c;其消費特點和市場前景值得深入探討。 首先&#xff0c;從消費特點來看…

基于YOLOv5的道路裂縫檢測,加入一種基于內容引導注意力(CGA)的混合融合提升2個多點

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文主要內容:詳細介紹道路裂縫檢測整個過程&#xff0c;從數據集到訓練模型到結果可視化分析。 &#x1f4a1;&#x1f4a1;&#x1f4a1;通過加入一種基于內容引導注意力(CGA)的混合融合提升檢測性能&#xff0c; 特征融合創新 | 一…

WS2812C是一款將控制電路和RGB芯片集成在一個5050元器件封裝中的智能控制LED光源

一般說明 WS2812C是一款將控制電路和RGB芯片集成在一個5050元器件封裝中的智能控制LED光源。內部包括智能數字端口數據鎖存器和信號整形放大驅動電路。還包括一個精密的內部振蕩器和一個 12V電壓可編程恒流控制部分&#xff0c;有效保證像素點光源顏色高度一致。 …

決策規劃仿真平臺的搭建

以下內容筆記據來自于b站up主忠厚老實的老王&#xff0c;視頻&#xff1b;鏈接如下&#xff1a; 自動駕駛決策規劃算法第二章第一節 決策規劃仿真平臺搭建_嗶哩嗶哩_bilibili 使用到的軟件有matlab、prescan、carsim以及visual stadio。 我電腦上軟件的版本是matlab2022a&am…

2024.1IDEA 到2026年

鏈接&#xff1a;https://pan.baidu.com/s/1hjJEV5A5k1Z9JbPyBXywSw?pwd9g4i 提取碼&#xff1a;9g4i解壓之后,按照 操作說明.txt 操作; IntelliJ IDEA 2024.1 (Ultimate Edition) Build #IU-241.14494.240, built on March 28, 2024 Licensed to gurgles tumbles You have…

Python代碼:二、多行輸出

1、題目 將字符串 Hello World! 存儲到變量str1中&#xff0c;再將字符串 Hello Nowcoder! 存儲到變量str2中&#xff0c;再使用print語句將其打印出來&#xff08;一行一個變量&#xff09;。 2、代碼 import sys str1 Hello World! str2 Hello Nowcoder! print (str1,st…

詳細分清Session,Cookie和Token之間的區別,以及JWT是什么東西

Cookie Cookie是一種小型的文本文件&#xff0c;由網站在用戶訪問時存儲在其計算機或移動設備上&#xff0c;Cookie主要用于跟蹤、識別和存儲有關用戶的信息。 簡單來說Cookie就是用來存儲某些后端發送給前端的數據&#xff0c;例如我們登陸后&#xff0c;后端會返回一個登錄…

Vue3 + Avue中 Header slot寫法

avue示例 <template><avue-crud ref"crud":option"option":data"data"><template #name-header"{column}"><el-tag>{{(column || {}).label}}-{{(column || {}).prop}}</el-tag></template><…

02、網絡協議、IP地址、網絡狀況、網絡異質性問題的解決

聲明&#xff1a;本教程不收取任何費用&#xff0c;歡迎轉載&#xff0c;尊重作者勞動成果&#xff0c;不得用于商業用途&#xff0c;侵權必究&#xff01;&#xff01;&#xff01; 目錄 前言 一、IP地址 二、網絡協議 三、網絡狀況【了解】 四、網絡異質性問題的解決 前…