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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

两个栈实现队列操作

發(fā)布時間:2025/5/22 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 两个栈实现队列操作 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近看了個面試的帖子講的是“怎么用兩個棧來實現(xiàn)隊列的操作”,好奇的我也想試下這道題目,咋一看這道題目挺簡單的呀,嗯,確實不難。先簡單講下我第一眼看到這個題目時想到的解法。講解法之前先給大家講下數(shù)據(jù)結(jié)構(gòu)中的棧和隊列吧,免得有的人不明白棧和隊列,那就沒辦法繼續(xù)看下去了。

棧(stack)(wiki)

我們經(jīng)常會在面試中聽到“?!边@個詞語,理解這個概念對于理解程序的運行至關(guān)重要。棧這個詞語在不同的語境中表達的含義是不同的。下面我將解釋下棧的三種含義(參考:《Stack的三種含義》)。

  • 含義一:數(shù)據(jù)結(jié)構(gòu)

? 我們這里講的其實就是這種含義,stack是一種存儲數(shù)據(jù)的結(jié)構(gòu),特點是LIFO,即后進先出(last in First out)。

?

? 這種數(shù)據(jù)結(jié)構(gòu)其底層是用鏈表來現(xiàn)實的,最大特點是只能操作最上面的元素,所以先進棧的被壓在下面只能后出棧。

? 這種數(shù)據(jù)結(jié)構(gòu)通常又下面幾種方法來操作最上面的元素:

? push : 進棧

? pop : 出棧

? top : 獲取棧頂元素

? empty :判斷棧是否為空

  • 含義二:代碼的運行方式

    ? stack的第二種含義是“調(diào)用?!?#xff0c;表示函數(shù)像積木一樣的堆放,以供層層調(diào)用,我們在函數(shù)中的遞歸就是用堆棧實現(xiàn)的,遞歸簡單點來說就是函數(shù)中調(diào)用該函數(shù)。

  • 含義三:內(nèi)存區(qū)域

    stack的第三種含義就是存儲數(shù)據(jù)的一種內(nèi)存區(qū)域。程序在運行時需要一定的空間來存儲數(shù)據(jù)。一般來說系統(tǒng)會劃分出兩種不同的內(nèi)存空間,一種是棧(stack),另一種是堆(heap)。

    棧是由操作系統(tǒng)自動分配和釋放的,存放函數(shù)的參數(shù)值,局部變量值等。堆一般由程序員分配并釋放,若程序員不釋放,程序結(jié)束時可能由OS回收,分配方式類似于鏈表。我們經(jīng)常講的內(nèi)存泄漏其實就是指的就是堆。

介紹完了棧的定義,簡單說下棧和隊列的區(qū)別吧,棧的特點是先進的后出,隊列的特點是先進的先出。這道題目考查的重點還是對于棧和隊列特性的理解,其次再加上一些思考就好了。

看完這道題目我其實第一反應(yīng)就覺得這道題挺簡單的,新建兩個棧s1、s2,然后當(dāng)有入棧請求的時候先將s1棧中的數(shù)據(jù)依次出棧進入到s2的棧中,然后將新請求入棧的數(shù)據(jù)放入s1中,最后將s2棧中數(shù)據(jù)依次出棧進入到s1棧中。每次有出棧請求的時候?qū)1棧中的數(shù)據(jù)出棧就好了。這種解法應(yīng)該是比較常規(guī)的解法,也比較容易想到的。

但是仔細想下這種方法效率比較低,有頻繁的出棧和入棧操作,對于性能的影響比較大,那有沒有什么更好的方法能解決這個問題呢?其實我們可以在出棧的時候把棧底元素取出來,入棧的時候正常入棧。具體實現(xiàn)就是當(dāng)有入棧請求的時候?qū)?shù)據(jù)壓入棧s1,當(dāng)有出棧請求的時候?qū)1數(shù)據(jù)依次出棧壓入s2棧中,那么這時s2的棧頂元素就是s1的棧底元素,最后將s2的數(shù)據(jù)又依次壓入s1中。這么這樣的話就只有出棧的操作會有頻繁的棧操作,對于入棧來講沒有額外的棧操作。這種方法其實效率已經(jīng)非常高了。

其實還有一種效率更高的方法來解決這個問題,仔細想下這么問題,將上面的解法做個優(yōu)化,將s1棧中的數(shù)據(jù)依次壓入s2中后又依次壓入s1中,那為什么又要將s2中的數(shù)據(jù)重新壓回s1呢?其實這步操作可以避免,我們可以當(dāng)有入棧的操作時將數(shù)據(jù)壓入s1,當(dāng)有出棧操作時將s2中的數(shù)據(jù)出棧,若s2棧為空,則將s1中的數(shù)據(jù)全部依次壓入s2中,這樣的方法效率會比上面的方法更優(yōu)。

下面的代碼就是上面提到的最后一種方法的實現(xiàn):

#include <iostream> #include <cstdio> #include <stack> #include <algorithm>using namespace std; std::stack<int>s1, s2; int main() {printf("Please input argument:1 push,2 pop\n");int operation, num;while(scanf("%d", &operation) != EOF){if(operation == 1){printf("please input queue push num:");scanf("%d", &num);s1.push(num);}else if(operation ==2){if(!s2.empty()){printf("Queue pop num: %d\n", s2.top());s2.pop();}else if(!s1.empty()){while(!s1.empty()){s2.push(s1.top());s1.pop();}printf("Queue pop num: %d\n", s2.top());s2.pop();}else{printf("queue empty\n");}}else{printf("Input invalid, please input repeat");}}return 0; } 復(fù)制代碼

轉(zhuǎn)載于:https://juejin.im/post/5c83371ef265da2dac457fa5

總結(jié)

以上是生活随笔為你收集整理的两个栈实现队列操作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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