欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

圖解C++的STL之stack和queue,輕松理解數(shù)據(jù)結(jié)構(gòu)

 更新時(shí)間:2024年03月13日 08:38:02   作者:?舊言~  
聚焦?C++?的?STL?中的?stack?和?queue,讓數(shù)據(jù)結(jié)構(gòu)變得簡(jiǎn)單有趣!?通過(guò)圖解的方式,我們將輕松理解這兩個(gè)重要的數(shù)據(jù)結(jié)構(gòu),準(zhǔn)備好開(kāi)啟?STL?學(xué)習(xí)之旅了嗎?讓我們一起探索?stack?和?queue?的奧秘吧!

前言

今天咱們學(xué)習(xí)stack和queue,咱們還是依照官網(wǎng)來(lái)學(xué)習(xí):

stack - C++ Reference (cplusplus.com)

queue - C++ Reference (cplusplus.com)

主體

        在數(shù)據(jù)結(jié)構(gòu)初階中,我們模擬實(shí)現(xiàn)了stack和queue,只能說(shuō)我們知道棧和隊(duì)列,但是棧和隊(duì)列的底層是如何實(shí)現(xiàn)的我們就不得而知了,面對(duì)這個(gè)現(xiàn)象我們從新學(xué)習(xí)棧和隊(duì)列,深度解剖。學(xué)習(xí)這個(gè)版塊,咱們按照下面的圖解進(jìn)行學(xué)習(xí):

stack的介紹和使用

stack的介紹

stack - C++ Reference (cplusplus.com)

stack是一種容器適配器,其本質(zhì)是數(shù)據(jù)結(jié)構(gòu)中的棧。它是一種只能在一端進(jìn)行插入和刪除操作的線性表。stack是作為容器適配器被實(shí)現(xiàn)的,容器適配器即是對(duì)特定類(lèi)封裝作為其底層的容器,并提供一組特定的成員函數(shù)來(lái)訪問(wèn)其元素,將特定類(lèi)作為其底層的,元素特定容器的尾部(即棧頂)被壓入和彈出。標(biāo)準(zhǔn)容器vector、deque、list均符合這些需求,默認(rèn)情況下,如果沒(méi)有為stack指定特定的底層容器,默認(rèn)情況下使用deque。棧和隊(duì)列都叫做適配器/配接器,不是直接實(shí)現(xiàn)的,而是封裝其他容器,包裝轉(zhuǎn)換實(shí)現(xiàn)出來(lái)的stack的底層容器可以是任何標(biāo)準(zhǔn)的容器類(lèi)模板或者一些其他特定的容器類(lèi),這些容器類(lèi)應(yīng)該支持以下: empty:判空操作。back:獲取尾部元素的操作,這是因?yàn)闂5膖op操作相當(dāng)于拿取尾部元素。push_back:尾部插入元素操作。pop_back:尾部刪除元素操作。

 stack的使用

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

代碼訓(xùn)練:

#include<iostream>
#include<stack>
#include<queue>
 
using namespace std;
 
void test_stack()
{
    stack<int> st;
    st.push(1);
    st.push(2);
    st.push(3);
    st.push(4);
    st.push(5);
    
    cout << st.empty() << endl; // 檢測(cè)stack是否為空
    cout << st.size() << endl;  // 返回stack中元素的個(gè)數(shù)
    
    while (!st.empty())
    {
        cout << st.top() << " ";
        st.pop();
    }
    cout << endl;
}
int main()
{
    test_stack();
    return 0;
}

代碼訓(xùn)練:tack的案例,首先先創(chuàng)建一個(gè)stack容器,<int>這里表示我這個(gè)容器存放的是int類(lèi)型的數(shù)據(jù)。然后通過(guò)push()將數(shù)據(jù)壓入棧中,stack并不支持迭代器訪問(wèn),我們通過(guò)接口empty()判斷棧是否為空,通過(guò)top()訪問(wèn)棧頂元素,pop()將數(shù)據(jù)出棧。

stack的應(yīng)用

1.最小棧

問(wèn)題分析:設(shè)計(jì)兩個(gè)棧,一個(gè)負(fù)責(zé)保存棧的元素,一個(gè)負(fù)責(zé)保存棧的最小值。只要有元素比最小值棧的頂部元素還有小,那么,就將這個(gè)值壓入最小值棧中,這樣就能保證,最小值棧的頂部元素永遠(yuǎn)是當(dāng)前壓入的所有元素中最小的。

代碼:

class MinStack {
public:
    MinStack() 
    {
 
    }
    
    void push(int val) 
    {
        st.push(val);
        if(minst.empty() || val <= minst.top())
        {
            minst.push(val);
        }
    }
    
    void pop() 
    {
        if(minst.top() == st.top())
        {
            minst.pop();
        }
        st.pop();
    }
    
    int top() 
    {
        return st.top();
    }
    
    int getMin() 
    {
        return minst.top();
    }
private:
    stack<int> st;
    stack<int> minst; // 輔助棧
};

2.棧的壓入、彈出序列

問(wèn)題分析:借助一個(gè)輔助棧,首先,創(chuàng)建兩個(gè)變量i和j,分別指向pushV數(shù)組的元素和popV數(shù)組的元素,然后將pushV的數(shù)據(jù)壓入棧中,直到遇到頂部元素恰好等于出棧序列的元素,那么就將棧頂元素出棧,并且j++。最后,如果棧的元素不為空,那么說(shuō)明當(dāng)前出棧序列不符合。

代碼:

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) 
    {
        stack<int> st;
        int i = 0, j = 0; // i 指向push數(shù)組的元素 , j 指向pop數(shù)組元素
        for(; i < pushV.size();i++)
        {
            st.push(pushV[i]);
            while(!st.empty() && st.top() == popV[j])
            {
                st.pop();
                j++;
            }
        }
        return st.empty();
    }
};

3.逆波蘭表達(dá)式求值

問(wèn)題分析:同樣借助一個(gè)輔助棧來(lái)完成,遍歷數(shù)組tokens,遇到數(shù)值就壓入棧中,遇到符號(hào),就彈出兩個(gè)元素,并且根據(jù)符號(hào)進(jìn)行求值。最后,棧頂元素就是最終的表達(dá)式結(jié)果。

class Solution {
public:
    int evalRPN(vector<string>& tokens) 
    {
        stack<int> st;
        for(int i = 0;i<tokens.size();++i)
        {
            if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/")
            {
                int num1 = st.top();
                st.pop();
                int num2 = st.top();
                st.pop();
                if(tokens[i] == "+") st.push(num2 + num1);
                else if(tokens[i] == "-") st.push(num2 - num1);
                else if(tokens[i] == "*") st.push(num2 * num1);
                else if(tokens[i] == "/") st.push(num2 / num1);
            }
            else 
            {
                st.push(stoi(tokens[i])); // stoi 把字符串轉(zhuǎn)為數(shù)字
            }
        }
        int result = st.top();
        st.pop();
        return result;
    }
};

4.用棧實(shí)現(xiàn)隊(duì)列

問(wèn)題分析:設(shè)計(jì)兩個(gè)棧,一個(gè)棧用來(lái)入數(shù)據(jù),一個(gè)棧用來(lái)出數(shù)據(jù)。入隊(duì)列操作,可以直接將數(shù)據(jù)插入到stIn中,出隊(duì)列的時(shí)候,如果stOut為空,就將stIn的數(shù)據(jù)放到stOut中,我們直到棧的特性是后進(jìn)先出,隊(duì)列的特性是先進(jìn)先出,那么將元素放到一個(gè)棧中,再出棧到另一個(gè)棧中,相當(dāng)于元素原本的順序不變,恰好符合隊(duì)列的要求。

代碼:

class MyQueue {
public:
    stack<int> stIn;  // 用來(lái)入數(shù)據(jù)
    stack<int> stOut; // 用來(lái)出數(shù)據(jù)
    MyQueue() 
    {
 
    }
    
    void push(int x) 
    {
        stIn.push(x);
    }
    
    int pop() 
    {
        if(stOut.empty())
        {
            while(!stIn.empty())
            {
                stOut.push(stIn.top());
                stIn.pop();
            }
        }
        int result = stOut.top();
        stOut.pop();
        return result;
    }
    // 獲取頭部元素
    int peek() 
    {
        int res = this->pop();
        stOut.push(res);
        return res;
    }
    
    bool empty() 
    {
        return stIn.empty() && stOut.empty();
    }
};

queue的介紹和使用

queue的介紹

queue - C++ Reference (cplusplus.com)

queue是一種容器適配器,專門(mén)用于在先進(jìn)先出上下文中操作,在容器的一端插入元素,另一端刪除元素。

queue的底層也是用作容器來(lái)進(jìn)行封裝,底層容器必須支持以下操作:

empty:檢測(cè)隊(duì)列是否為空。size:返回隊(duì)列的有效元素個(gè)數(shù)front:返回隊(duì)頭元素的引用back:返回隊(duì)尾元素的引用push_back:在隊(duì)列尾部入隊(duì)列pop_front:在隊(duì)列頭部出隊(duì)列

標(biāo)準(zhǔn)容器中的deque、list滿足了這些要求,默認(rèn)情況下,使用deque作為底層容器類(lèi)。

queue的使用

函數(shù)說(shuō)明接口說(shuō)明
empty檢測(cè)queue是否為空
size返回queue的元素個(gè)數(shù)
front返回隊(duì)頭元素的引用
back返回隊(duì)尾元素的引用
push在隊(duì)尾將元素入隊(duì)列
pop將隊(duì)頭元素出隊(duì)列

代碼訓(xùn)練:

#include<iostream>
#include<stack>
#include<queue>
 
using namespace std;
 
void test_queue()
{
    queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    q.push(4);
    q.push(5);
 
    cout << q.empty() << endl;
    cout << q.size() << endl;
    while (!q.empty())
    {
        cout << q.front() << " ";
        q.pop();
    }
    cout << endl;
}
int main()
{
    test_queue();
    return 0;
}

運(yùn)行結(jié)果:

queue的應(yīng)用

用隊(duì)列實(shí)現(xiàn)棧

問(wèn)題分析:使用兩個(gè)隊(duì)列,重點(diǎn)在于出棧操作,出棧操作,將隊(duì)列1的元素,放到隊(duì)列2,隊(duì)列1的元素只剩下1個(gè),然后這個(gè)作為出棧的元素,之后q1 = q2,然后將q2的元素進(jìn)行出隊(duì)。

class MyStack {
public:
    queue<int> q1;
    queue<int> q2;
    MyStack() {
 
    }
    
    void push(int x) {
        q1.push(x);
    }
    
    int pop() {
        int size = q1.size();
        size--;
        while(size--)
        {
            q2.push(q1.front());
            q1.pop();
        }
        int result = q1.front();
        q1.pop();
        q1 = q2;
        while(!q2.empty())
        {
            q2.pop();
        }
        return result;
    }
    
    int top() {
        return q1.back();
    }
    
    bool empty() {
        return q1.empty();
    }
};

priority_queue的介紹和使用

priority_queue的介紹

priority_queue::priority_queue - C++ Reference (cplusplus.com)

優(yōu)先級(jí)隊(duì)列是一種容器適配器,根據(jù)嚴(yán)格的弱排序標(biāo)準(zhǔn),它的第一個(gè)元素是所有元素中最大的。優(yōu)先級(jí)隊(duì)列的底層是用堆進(jìn)行實(shí)現(xiàn)的,大根堆的堆頂是最大的。標(biāo)準(zhǔn)容器vector和queue都滿足以上要求,如果沒(méi)有特定要求,默認(rèn)使用vector作為底層容器類(lèi)。需要支持隨機(jī)訪問(wèn)迭代器,保證內(nèi)部始終保持堆結(jié)構(gòu)。容器適配器在需要的時(shí)候調(diào)用算法函數(shù)make_heap、push_heap和pop_heap來(lái)自動(dòng)完成此操作。優(yōu)先級(jí)隊(duì)列的底層容器可以使任何標(biāo)準(zhǔn)容器類(lèi)模板,也可以是其他特定設(shè)計(jì)的容器類(lèi)。容器應(yīng)該可以通過(guò)隨機(jī)訪問(wèn)迭代器訪問(wèn),并支持以下操作: empty():檢測(cè)容器是否為空。size():返回容器有效元素個(gè)數(shù)。front():返回容器第一個(gè)元素的引用push_back():在容器尾部插入元素pop_back():刪除容器尾部元素 ??容器適配器 ??什么是適配器

適配器是一種設(shè)計(jì)模式,假設(shè)已經(jīng)有一個(gè)設(shè)計(jì)系統(tǒng),你需要把新的廠商類(lèi)整合進(jìn)去,但是,新的廠商類(lèi)的接口和原來(lái)的接口不一致,但是,又不可以修改原有的代碼,這個(gè)時(shí)候,就可以設(shè)計(jì)一個(gè)適配器作為中間人,實(shí)現(xiàn)所期望的接口,與新的廠商類(lèi)進(jìn)行對(duì)接。

 STL標(biāo)準(zhǔn)庫(kù)中stack和queue的底層結(jié)構(gòu)

stack和queue是對(duì)標(biāo)準(zhǔn)庫(kù)的其他容器的接口進(jìn)行了包裝,STL的stack和queue默認(rèn)使用deque。

deque的介紹和使用

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

到此這篇關(guān)于圖解C++的STL之stack和queue,輕松理解數(shù)據(jù)結(jié)構(gòu)的文章就介紹到這了,更多相關(guān)STL之stack和queue詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • QSS樣式表實(shí)現(xiàn)界面換膚功能

    QSS樣式表實(shí)現(xiàn)界面換膚功能

    這篇文章主要介紹了QSS樣式表實(shí)現(xiàn)界面換膚功能,對(duì)QSS樣式表進(jìn)行簡(jiǎn)單介紹,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10
  • 順序線性表的代碼實(shí)現(xiàn)方法

    順序線性表的代碼實(shí)現(xiàn)方法

    下面小編就為大家?guī)?lái)一篇順序線性表的代碼實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • 談?wù)凜++學(xué)習(xí)之Pair的使用方法

    談?wù)凜++學(xué)習(xí)之Pair的使用方法

    pair是一種模板類(lèi)型,其中包含兩個(gè)數(shù)據(jù)值,兩個(gè)數(shù)據(jù)的類(lèi)型可以不同,本篇詳細(xì)的介紹了Pair的使用方法和實(shí)例,有興趣的同學(xué)可以了解一下。
    2016-12-12
  • C++設(shè)計(jì)模式之模板方法模式

    C++設(shè)計(jì)模式之模板方法模式

    這篇文章主要介紹了C++設(shè)計(jì)模式之模板方法模式,本文講解了什么是模板方法模式、模板方法模式的UML類(lèi)圖、模板方法模式的使用場(chǎng)合等內(nèi)容,需要的朋友可以參考下
    2014-10-10
  • C++中函數(shù)模板的用法詳細(xì)解析

    C++中函數(shù)模板的用法詳細(xì)解析

    所謂函數(shù)模板實(shí)際上是建立一個(gè)通用函數(shù),其涵涵素類(lèi)型額形參類(lèi)型不具體指定,用一個(gè)虛擬的類(lèi)型來(lái)代表,這個(gè)通用函數(shù)就稱為函數(shù)模板
    2013-10-10
  • C++中日期類(lèi)的常見(jiàn)題目合集分享

    C++中日期類(lèi)的常見(jiàn)題目合集分享

    這篇文章主要為大家詳細(xì)介紹了一些C++中日期類(lèi)的常見(jiàn)題目,文中的示例代碼講解詳細(xì),對(duì)我們掌握C++有一定的幫助,感興趣的小伙伴可以了解一下
    2023-06-06
  • C++實(shí)現(xiàn)掃雷游戲

    C++實(shí)現(xiàn)掃雷游戲

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • C語(yǔ)言數(shù)組實(shí)現(xiàn)打磚塊游戲

    C語(yǔ)言數(shù)組實(shí)現(xiàn)打磚塊游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言數(shù)組實(shí)現(xiàn)打磚塊游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 詳解C/C++如何發(fā)送與接收Kafka消息

    詳解C/C++如何發(fā)送與接收Kafka消息

    系統(tǒng)之間通信方式很多如:系統(tǒng)之間調(diào)用(http/rpc等),異步間接調(diào)用如發(fā)送消息、公共存儲(chǔ)等,算法工程為C/C++工程,本文將介紹如何在C/C++中如何發(fā)送與接收Kakfa消息(包含:Kafka的SASL認(rèn)證方式),并提供了詳細(xì)的源碼和講解,需要的朋友可以參考下
    2024-07-07
  • 使用opencv拉伸圖像擴(kuò)大分辨率示例

    使用opencv拉伸圖像擴(kuò)大分辨率示例

    這篇文章主要介紹了使用opencv拉伸圖像擴(kuò)大分辨率示例,需要的朋友可以參考下
    2014-04-04

最新評(píng)論