色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

棧與C++中的std::stack詳解

冬至子 ? 來源:iDoitnow ? 作者:艱默 ? 2023-07-18 16:53 ? 次閱讀

棧(stack)

什么是棧?

棧是一種線性的數據結構,其是一種運算受限(限定僅在表尾進行插入和刪除的線性表)的線性表。棧的結構類似下圖的容器:

圖片

如上圖所示,棧的結構就像一個端封閉,另一端開口的容器,往容器放入小球(對應棧中的元素),先放入的小球就越靠近容器的底部,最早進入的小球對應的位置就是 棧底 (bottom),最后放入的小球對應的位置就是 棧頂 (top),放入小球的動作就叫做 入棧 (push);取出小球的時候,只能按照放入順序相反的順序來取,即先取后放入的,再去先放入的,每次取小球的動作就叫做 出棧 (pop)。由于棧的單端口進出的限制,決定了棧中的元素只能先進后出(FILO, First In Last Out)。棧的數據結構可以使用數組來實現,也可以用鏈表來實現,具體如下圖所示:

圖片

棧的基本操作和應用

入棧(push)

入棧就是把元素存放入棧中,由于棧的結構只允許從一次存放元素,所以新元素的存入后所在的位置就是該棧新的棧頂,我們以棧的數組實現為例,入棧的過程如下圖所示:

圖片

出棧(pop)

出棧就是把元素從棧中彈出,同樣的由于棧結構單端進出的限制,出棧時候的元素就是棧頂對應的元素,取出元素后,出棧元素前面的那個元素對應的位置將變成新的棧頂。出棧的過程如下:

圖片

入棧和出棧的復雜度和應用場景

由于棧的后進先出的特性,使得入棧和出棧只會影響到棧中最后一個元素,不會涉及到其他元素的移動,因此入棧和出棧的時間復雜都為。同樣的,棧的先入后出的特性,也使得棧不能擁有遍歷、隨機訪問和隨機插入的功能。

由于棧的特殊結構,棧常用于以下場景:

  • 逆序輸出:由于棧先入后出的特性,使用棧結構可以輕松實現逆序輸出的操作。
  • 語法檢測:對于一些成對出現的符號,如"[]"、"()"等,凡是遇到符號的前半部分,即入棧(push)該符號,凡是遇到括號后半部分的,就與棧頂元素進行匹配,如果匹配成功,則出棧(pop),否則就是匹配失敗,語法錯誤。
  • 數字進制轉換:順序計算,繼續結果逆序輸出。

棧的應用場景還有很多,這里就不一一舉例,實際上棧的應用都是基于棧的先入后出的特性。

類模板std::satck

stack類是C++標準庫提供的一個容器適配器,它給使用者提供了棧的功能,實現的棧的先進后出(FILO)的數據結構,并提供了特定的函數集合,其定義如下所示:

template<
    class T,
    class Container = std::deque< T >
> class stack;

該類模板在頭文件中定義。

形參T和Container

  • T :代表存儲元素的類型
  • Container :用于存儲元素的底層容器類型。該類型必須滿足序列容器的要求,同時該容器類型能夠提供通常語義下的back()、push_back()和pop_back()函數。默認情況下使用標準容器std::deque。滿足該要求的標準容器還有std::vector和std::list。

成員函數

元素訪問

訪問棧頂元素使用top()函數,該函數的定義如下:

reference top();
const_reference top() const;

該函返回棧中棧頂元素的引用。實際上調用的就是底層容器的back()。

棧的容量
  • size :返回底層容器中的元素數 。實際上調用的就是底層容器的size()。
  • empty :檢查底層容器是否為空,如果為空返回true,否則false。實際上調用的就是底層容器的empty()。
棧的修改
  • push :向棧中推入元素。其函數聲明如下:
void push( const value_type& value );
void push( value_type&& value ); //C++11 起
  • emplace :推入新元素到棧中,與push不同的是該函數是原位構造元素(直接在容器內構造對象,不用拷貝一個復制品再使用),既不進行也不進行復制操作。其函數聲明如下:
template< class... Args >
void emplace( Args&&... args ); //C++11 起 C++17 前

template< class... Args >
decltype(auto) emplace( Args&&... args ); //C++17 起

其中args為轉發給元素構造函數的參數。也正是由于emplace的原位構造元素,省去了拷貝構造的過程,使得emplace的效率高于push。

  • pop :從棧中移除站定元素。實際上調用的就是底層元素的pop_back()。
  • swap :交換棧與另一個棧中的內容,其函數聲明如下:
void swap( stack& other ) noexcept(/* see below */); //C++11 起

用法示例

#include < iostream >
#include < stack >
using namespace std;
int main() {
    stack< int > s;

    // push()
    s.push(1);
    s.push(2);
    s.push(3);

    cout < < "按順push元素1、2、3后" < < endl;
    cout < < "棧s中元素的數量, 即s.size() = " < < s.size() < < endl;
    cout < < "此時, 棧s是否為空,即s.empty() = " < < s.empty() < < endl;
    if (!s.empty())
        cout < < "此時, 棧s非空, 棧頂元素,即s.top() = " < < s.top() < < endl;
    else
        cout < < "此時, 棧s為空, 不能使用top訪問棧頂元素 = " < < s.top() < < endl;

    s.pop();  // 彈出棧頂元素
    cout < < "n彈出棧頂元素3, 即pop()后" < < endl;
    cout < < "棧s中元素的數量, 即s.size() = " < < s.size() < < endl;
    cout < < "此時, 棧s是否為空,即s.empty() = " < < s.empty() < < endl;
    if (!s.empty())
        cout < < "此時, 棧s非空, 棧頂元素,即s.top() = " < < s.top() < < endl;
    else
        cout < < "此時, 棧s為空, 不能使用top訪問棧頂元素 = " < < s.top() < < endl;

    s.pop();
    cout < < "n彈出棧頂元素2, 即pop()后" < < endl;
    cout < < "棧s中元素的數量, 即s.size() = " < < s.size() < < endl;
    cout < < "此時, 棧s是否為空,即s.empty() = " < < s.empty() < < endl;
    if (!s.empty())
        cout < < "此時, 棧s非空, 棧頂元素,即s.top() = " < < s.top() < < endl;
    else
        cout < < "此時, 棧s為空, 不能使用top訪問棧頂元素 = " < < s.top() < < endl;

    s.pop();
    cout < < "n彈出棧頂元素1, 即pop()后" < < endl;
    cout < < "棧s中元素的數量, 即s.size() = " < < s.size() < < endl;
    cout < < "此時, 棧s是否為空,即s.empty() = " < < s.empty() < < endl;
    if (!s.empty())
        cout < < "此時, 棧s非空, 棧頂元素,即s.top() = " < < s.top() < < endl;
    else
        cout < < "此時, 棧s為空, 不能使用top訪問棧頂元素" < < endl;

    // swap()操作
    s.emplace(1);
    s.emplace(2);
    s.emplace(3);

    stack< int > s1;

    cout < < "n-----------棧s和s1交換前----------" < < endl;
    cout < < "ns的狀態: " < < endl;
    cout < < "棧s中元素的數量, 即s.size() = " < < s.size() < < endl;
    cout < < "此時, 棧s是否為空,即s.empty() = " < < s.empty() < < endl;
    if (!s.empty())
        cout < < "此時, 棧s非空, 棧頂元素,即s.top() = " < < s.top() < < endl;
    else
        cout < < "此時, 棧s為空, 不能使用top訪問棧頂元素" < < endl;

    cout < < "ns1的狀態: " < < endl;
    cout < < "棧s1中元素的數量, 即s1.size() = " < < s1.size() < < endl;
    cout < < "此時, 棧s1是否為空,即s1.empty() = " < < s1.empty() < < endl;
    if (!s1.empty())
        cout < < "此時, 棧s1非空, 棧頂元素,即s1.top() = " < < s1.top() < < endl;
    else
        cout < < "此時, 棧s1為空, 不能使用top訪問棧頂元素" < < endl;

    s1.swap(s);  // s和s1進行交換

    cout < < "n-----------棧s和s1交換后----------" < < endl;
    cout < < "ns的狀態: " < < endl;
    cout < < "棧s中元素的數量, 即s.size() = " < < s.size() < < endl;
    cout < < "此時, 棧s是否為空,即s.empty() = " < < s.empty() < < endl;
    if (!s.empty())
        cout < < "此時, 棧s非空, 棧頂元素,即s.top() = " < < s.top() < < endl;
    else
        cout < < "此時, 棧s為空, 不能使用top訪問棧頂元素" < < endl;

    cout < < "ns1的狀態: " < < endl;
    cout < < "棧s1中元素的數量, 即s1.size() = " < < s1.size() < < endl;
    cout < < "此時, 棧s1是否為空,即s1.empty() = " < < s1.empty() < < endl;
    if (!s1.empty())
        cout < < "此時, 棧s1非空, 棧頂元素,即s1.top() = " < < s1.top() < < endl;
    else
        cout < < "此時, 棧s1為空, 不能使用top訪問棧頂元素" < < endl;

    return 0;
}

輸出結果:

按順push元素12、3后
棧s中元素的數量, 即s.size() = 3
此時, 棧s是否為空,即s.empty() = 0
此時, 棧s非空, 棧頂元素,即s.top() = 3

彈出棧頂元素3, 即pop()后
棧s中元素的數量, 即s.size() = 2
此時, 棧s是否為空,即s.empty() = 0
此時, 棧s非空, 棧頂元素,即s.top() = 2

彈出棧頂元素2, 即pop()后
棧s中元素的數量, 即s.size() = 1
此時, 棧s是否為空,即s.empty() = 0
此時, 棧s非空, 棧頂元素,即s.top() = 1

彈出棧頂元素1, 即pop()后
棧s中元素的數量, 即s.size() = 0
此時, 棧s是否為空,即s.empty() = 1
此時, 棧s為空, 不能使用top訪問棧頂元素

-----------棧s和s1交換前----------

s的狀態: 
棧s中元素的數量, 即s.size() = 3
此時, 棧s是否為空,即s.empty() = 0
此時, 棧s非空, 棧頂元素,即s.top() = 3

s1的狀態: 
棧s1中元素的數量, 即s1.size() = 0
此時, 棧s1是否為空,即s1.empty() = 1
此時, 棧s1為空, 不能使用top訪問棧頂元素

-----------棧s和s1交換后----------

s的狀態: 
棧s中元素的數量, 即s.size() = 0
此時, 棧s是否為空,即s.empty() = 1
此時, 棧s為空, 不能使用top訪問棧頂元素

s1的狀態: 
棧s1中元素的數量, 即s1.size() = 3
此時, 棧s1是否為空,即s1.empty() = 0
此時, 棧s1非空, 棧頂元素,即s1.top() = 3
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 適配器
    +關注

    關注

    8

    文章

    1970

    瀏覽量

    68239
  • 交換機
    +關注

    關注

    21

    文章

    2656

    瀏覽量

    100141
  • C++語言
    +關注

    關注

    0

    文章

    147

    瀏覽量

    7027
收藏 人收藏

    評論

    相關推薦

    c++和隊列

    stack ,(堆棧),是一種先進后出(First In Last Out,FILO)的數據結構,先插入的數據在底,后放入的數據在頂,所有的數據只能從
    的頭像 發表于 07-15 08:50 ?1026次閱讀
    <b class='flag-5'>c++</b>之<b class='flag-5'>棧</b>和隊列

    隊列與C++的queue詳解

    隊列就是一種線性的數據結構,它與日常生活中排隊的隊列相似,即先進先出(LIFO, First In First Out),這點也是它與Stack)的最大不同之處。
    的頭像 發表于 07-18 17:31 ?1777次閱讀
    隊列與<b class='flag-5'>C++</b><b class='flag-5'>中</b>的queue<b class='flag-5'>詳解</b>

    鴻蒙c++模板開發詳解

    鴻蒙c++模板開發詳解
    發表于 09-11 15:28

    Z-stack協議是什么

    本篇文章:主要是協議的介紹,使用協議完成一個簡單例子,協調器創建網絡的相關問題,學會在協議自定義事件等。正文如下:一、Zigbee協議
    發表于 01-12 07:49

    C++ 語言命令詳解(第二版)

    電子發燒友網站提供《C++ 語言命令詳解(第二版).txt》資料免費下載
    發表于 07-28 13:06 ?0次下載

    圖文詳解C++虛表的剖析

    圖文詳解C++虛表的剖析
    的頭像 發表于 06-29 14:23 ?2579次閱讀
    圖文<b class='flag-5'>詳解</b>:<b class='flag-5'>C++</b>虛表的剖析

    圖文詳解C++的輸出輸入

    圖文詳解C++的輸出輸入
    的頭像 發表于 06-29 14:53 ?3419次閱讀
    圖文<b class='flag-5'>詳解</b>:<b class='flag-5'>C++</b>的輸出輸入

    C++如何用虛函數實現多態

    01 — C++虛函數探索 C++是一門面向對象語言,在C++里運行時多態是由虛函數和純虛函數實現的,現在我們看下在C++如何用虛函數實現
    的頭像 發表于 09-29 14:18 ?1730次閱讀

    C++輸入和輸出的真實面目

    C++輸入和輸出 在C++std::cin、std::cout、std::cerr和std::
    的頭像 發表于 09-29 15:22 ?1812次閱讀

    單片機的堆和(Heap & Stack詳解

    一、程序內存分配由c/C++編譯的程序占用的內存分為以下幾個部分1、區(stack)— 由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似于數據結構
    發表于 01-13 15:39 ?7次下載
    單片機的堆和<b class='flag-5'>棧</b>(Heap & <b class='flag-5'>Stack</b>)<b class='flag-5'>詳解</b>

    詳解C/C++堆棧的工作機制

    參數,事實上是把參數壓入堆棧,聽起來,堆棧象一個大雜燴。那么,堆棧(Stack)到底是如何工作的呢?本文將詳解C/C++堆棧的工作機制。閱讀時請注意以下幾點:
    的頭像 發表于 07-29 09:09 ?1190次閱讀

    C++ std::tie函數的作用和用法

    C++std::tie函數的作用就是從元素引用中生成一個tuple元組,其在頭文件定義
    的頭像 發表于 07-18 17:28 ?890次閱讀

    ?數組和C++ std::array詳解

    std::array是C++容器庫提供的一個固定大小數組的容器。其與內置的數組相比,是一種更安全、更容易使用的數組類型。
    的頭像 發表于 07-19 11:02 ?1166次閱讀
    ?數組和<b class='flag-5'>C++</b> <b class='flag-5'>std</b>::array<b class='flag-5'>詳解</b>

    動態數組和C++ std::vector詳解

    std::vector是C++的默認動態數組,其與array最大的區別在于vector的數組是動態的,即其大小可以在運行時更改。std::vector是封裝動態數組的順序容器,且該容器中元素的存取是連續的。
    的頭像 發表于 07-19 11:07 ?1033次閱讀

    e2 studio調試MCU stack設置及查看

    e2 studio調試MCU stack設置及查看
    的頭像 發表于 10-27 10:38 ?986次閱讀
    e2 studio調試MCU <b class='flag-5'>stack</b><b class='flag-5'>棧</b>設置及查看
    主站蜘蛛池模板: 狠狠躁天天躁小说 | 日韩视频中文字幕精品偷拍 | 色尼玛亚洲综合 | 狠狠躁天天躁小说 | 色橹橹欧美在线观看视频高 | 亚洲一区二区三区免费看 | 两个人的视频日本在线观看完整 | 午夜看片福利在线观看 | 精品成人片深夜 | 欧美一区二区三区男同 | 欧洲精品不卡1卡2卡三卡四卡 | 精品欧美一区二区三区久久久 | 777久久人妻少妇嫩草AV蜜桃 | 视频一区视频二区ae86 | 俄罗斯18xv在线观看 | 喜马拉雅听书免费版 | 国产永久视频 | 精品国产中文字幕在线视频 | 九九色精品国偷自产视频 | 视频一区国产精戏刘婷30 | 国产国产成人人免费影院 | 三级叫床震大尺度视频 | 在线免费观看国产视频 | 日韩午夜欧美精品一二三四区 | 嫩草影院在线观看精品视频 | 中国国产不卡视频在线观看 | 色欲精品久久人妻AV中文字幕 | 久久99精品久久久久久园产越南 | 美女扒开腿让男生桶免费看动态图 | 99热久久这里只有精品 | 国产99精品在线观看 | 亚洲AV蜜桃永久无码精品无码网 | 国产精品第九页 | 女生扒开下面 | 国产 交换 丝雨 巅峰 | 含羞草国产亚洲精品岁国产精品 | 黄色三级在线 | 婷婷色色狠狠爱 | 亚洲欧洲日产国产 最新 | 桃花免费高清在线观看 | 三级黄网站 |