日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

复习栈和队列,详解最小栈,栈的弹出压入序列,逆波兰表达式求值

發(fā)布時(shí)間:2023/11/30 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 复习栈和队列,详解最小栈,栈的弹出压入序列,逆波兰表达式求值 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

棧和隊(duì)列的概念

棧:吃進(jìn)去吐出來(lái)
對(duì)列:吃進(jìn)去拉出來(lái)

數(shù)據(jù)結(jié)構(gòu)中的棧和內(nèi)存中的區(qū)別

數(shù)據(jù)結(jié)構(gòu)中的棧具有后進(jìn)先出的特性,而內(nèi)存中的棧是一個(gè)內(nèi)存空間,只不過(guò)這個(gè)內(nèi)存空間具與數(shù)據(jù)結(jié)構(gòu)的棧具有相同的特性。

棧和隊(duì)列操作

棧和隊(duì)列基本操作

棧操作


棧中沒(méi)有迭代器,因?yàn)椴恍枰闅v元素。

最小棧

棧里面肯定有,push/pop/top操作,而且三個(gè)操作的時(shí)間復(fù)雜度是---->O(1)
我們要添加一個(gè)操作是 獲取最小值的操作------>O(1)
對(duì)于一個(gè)普通的棧,要獲取它的最小的元素,它的時(shí)間復(fù)雜度就不一定是O(1),因?yàn)橹挥邪言胤旁跅m斘恢貌拍苋?/p>

具體操作

第一種方法

用一個(gè)棧,一次性壓入兩個(gè)元素,比如我要壓入2,此時(shí)棧空,那么這個(gè)2也就是棧中最小值,我們規(guī)定第一次壓入的2代表?xiàng)V械臄?shù)據(jù),而第二次我們?cè)侔?壓入代表?xiàng)V凶钚≡亍?br /> 如果此時(shí)再來(lái)了一個(gè)數(shù)是1,那么我門(mén)先拿這個(gè)數(shù)與棧頂元素也就是棧中最小值進(jìn)行比較,小,那么我們?cè)賶喝雰纱?,兩個(gè)1代表的意思跟上面的2一樣
如果此時(shí)再來(lái)一個(gè)3,我們拿3與棧頂元素也就是棧中最小值進(jìn)行比較,大,那么我們第一次壓入棧中數(shù)據(jù)元素3,第二次壓入1,也就是始終保持物理上的棧頂元素是最小的,但是理論上的棧頂元素是物理上的棧頂元素的下一個(gè)元素。

第二種方法

用兩個(gè)棧,一個(gè)放數(shù)據(jù),另外一個(gè)放最小值

最小棧實(shí)現(xiàn)

棧的彈出壓入序列

給兩個(gè)序列,一個(gè)是彈出的序列,另外一個(gè)是壓入的序列,看看彈出序列是否匹配壓入序列

  • 入棧: 如果棧是空的或者棧頂元素不等于出棧序列的當(dāng)前元素
  • 出棧,如果棧頂元素等于出棧序列,出棧。
  • class Solution { public:bool IsPopOrder(vector<int> pushV,vector<int> popV) {//入棧序列和出棧序列的個(gè)數(shù)都不一樣,那么肯定不匹配if(pushV.size() != popV.size())return false;stack<int>s;size_t inIdx=0; //標(biāo)記入棧元素size_t outIdx=0; //標(biāo)記待出棧元素while(outIdx < popV.size()){while(s.empty()|| s.top() != popV[outIdx]){if(inIdx < pushV.size())s.push(pushV[inIdx++]);elsereturn false ;}s.pop();++outIdx;}return true;} };

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

  • 必須用到棧 stack<int>s;用來(lái)保存所遇到的數(shù)字

  • 依次取表達(dá)式種的每一項(xiàng),for (size_t i = 0; i < tokens.size(); ++i)

  • 每一項(xiàng)是有可能是數(shù)字或者操作符,需要判斷一下if (!("+" == str || "-" == str || "*" == str || "/" == str))

  • 如果是數(shù)字,每項(xiàng)都是字符串,所以需要atoi轉(zhuǎn)化一下,再入棧s.push(atoi(str.c_str()));

  • 取操作符,到棧中取當(dāng)前操作符的左右操作數(shù)

    int right = s.top(); s.pop(); int left = s.top(); s.pop();
  • 選擇是什么類(lèi)型的運(yùn)算,并進(jìn)行元素后再次入棧

    switch (str[0]) {case'+':s.push(left + right);break;case'-':s.push(left - right);break;case'*':s.push(left * right);break;case'/'://題目中說(shuō)了右操作數(shù)不會(huì)為0 s.push(left / right);break; }
  • 結(jié)果就在棧頂位置,return s.top();

  • class Solution { public:int evalRPN(vector<string>& tokens) {stack<int> s;for (size_t i = 0; i < tokens.size(); ++i){string& str = tokens[i];if (!("+" == str || "-" == str || "*" == str || "/" == str)){//數(shù)字s.push(atoi(str.c_str()));}else{//操作符int right = s.top();s.pop();int left = s.top();s.pop();switch (str[0]){case'+':s.push(left + right);break;case'-':s.push(left - right);break;case'*':s.push(left * right);break;case'/':s.push(left / right);break;}}}return s.top();} };

    隊(duì)列操作

    二叉樹(shù)層序遍歷

    /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*///用來(lái)表示隊(duì)列中存放的數(shù)據(jù)類(lèi)型struct levelNode{int level;TreeNode *root;}; class Solution { public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>>ret;if(root==NULL){return ret;}queue<TreeNode*> q;q.push(root); //已經(jīng)將第一層的所有結(jié)點(diǎn)放到隊(duì)列種while(!q.empty()){//一次型將s一層的所有結(jié)點(diǎn)遍歷完vector<int > level;int levelSize =q.size();for(size_t i = 0; i< levelSize;++i){TreeNode * pCur =q.front();level.push_back(pCur->val);//如果該結(jié)點(diǎn)有左右子樹(shù)if(pCur->left)q.push(pCur->left);if(pCur->right)q.push(pCur->right);q.pop();}ret.push_back(level);}return ret;} };

    總結(jié)

    以上是生活随笔為你收集整理的复习栈和队列,详解最小栈,栈的弹出压入序列,逆波兰表达式求值的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。