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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法图解:如何用两个栈实现一个队列?

發布時間:2025/3/11 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法图解:如何用两个栈实现一个队列? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者 | 王磊

來源 | Java中文社群(ID:javacn666)

轉載請聯系授權(微信ID:GG_Stone)

本文已收錄至 https://github.com/vipstone/algorithm 《算法圖解》系列。

隊列和棧是計算機中兩個非常重要的數據結構,經過前面的學習(《隊列》、《棧》)我們知道了它們各自的特點,隊列是先進先出(FIFO)的,而棧是先進后出(FILO)的,那如何用棧來實現隊列呢?這可是一道經典的面試題,所以本文我們就來實現一下。

在正式開始之前,我們先來回顧一下棧和隊列的常用方法。

棧(Stack)的常用方法包含以下這些:

  • push():入棧方法,向棧頂添加元素;

  • pop():出棧方法,將棧頂的元素移除并返回元素;

  • peek():查詢棧頂元素,并不會移除元素。


隊列(Queue)的常用方法包含以下這些:

  • offer():入隊方法,向隊尾添加元素;

  • poll():出隊方法,從隊頭移除并返回元素;

  • peek():查詢隊頭元素,并不會移除元素。

有了這些前置知識,接下來我們來看今天的題目。

題目描述

用兩個棧實現一個隊列。隊列的聲明如下,請實現它的兩個函數 appendTail 和 deleteHead,分別完成在隊列尾部插入整數和在隊列頭部刪除整數的功能,若隊列中沒有元素,deleteHead 操作返回 -1。

示例 1:

輸入:

["CQueue","appendTail","deleteHead","deleteHead"]

[[],[3],[],[]]

輸出:[null,null,3,-1]

示例 2:

輸入:

["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]

[[],[],[5],[2],[],[]]

輸出:[null,-1,null,null,5,2]

提示:

1 <= values <= 10000

最多會對?appendTail、deleteHead 進行?10000?次調用

leetcode:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/

解題思路

這道題目的意思其實很好理解,就是要將先進后出的棧改為先進先出的隊列,其實問題中也給出了一些提示,“用兩個棧來實現一個隊列”。這道題實現的核心思想就是「負負得正」,我們先用一個棧來存入元素(這時最先進入的元素在棧底),然后再將第一個棧中的元素移動到新棧中,此時最先進入的元素就在棧頂了,然后在用第二個棧出棧時,整個執行的順序就變成了先進先出。

接下來,我們用圖解的方式來實現一下整個流程。

步驟一

先將元素入棧到第一個棧中,如下圖所示:

步驟二

將第一個棧中的元素都移動到第二個棧中,如下圖所示:

步驟三

所有元素從第二個棧中出棧,如下圖所示:

小結

從上述圖片可以看出,元素添加順序是 1、2、3,最終經過兩個棧之后的出棧順序也是 1、2、3,這樣我們就通過兩個棧實現了隊列(先進先出)。

實現代碼

接下來我們就用代碼來實現一下以上思路:

class?CQueue?{Stack<Integer>?inputStack;?//?入棧的容器(添加時操作)Stack<Integer>?outputStack;?//?出棧和查詢的棧容器public?CQueue()?{inputStack?=?new?Stack();outputStack?=?new?Stack();}//?添加操作public?void?appendTail(int?value)?{inputStack.push(value);}//?刪除操作public?int?deleteHead()?{if?(!outputStack.isEmpty())?{//?出棧容器不為空return?outputStack.pop();}?else?if?(!inputStack.isEmpty())?{//?入棧?stack?全部轉移到出棧?stackwhile?(!inputStack.isEmpty())?{outputStack.push(inputStack.pop());}}return?outputStack.isEmpty()???-1?:?outputStack.pop();} }

我們在 LeetCode 中提交以上測試代碼,執行結果如下:

注意事項

在整個實現過程中有兩個小細節需要特別注意一下:

  • 第 1 個棧只負責入棧(暫存數據),第 2 個棧只負責出棧(最終的隊列執行順序);

  • 每次棧 2 出棧時都要把所有的元素都出完之后,才能從棧 1 中追加(添加)新數據,當棧 2 的數據沒有全部出棧完成時,不能將棧 1 的元素入棧到棧 2,這樣會導致元素的執行順序混亂。

  • 總結

    本文我們通過兩個先進后出的棧,通過“負負得正”的思路實現了隊列先進先出的特性,但需要特別注意的是當第 2 個棧也就是出棧容器,在非空(棧)時不能將第 1 個棧中的元素添加到第 2 個棧中,以免造成程序執行順序混亂。

    往期推薦

    Java中的5大隊列,你知道幾個?

    2020-10-24

    一文詳解「隊列」,手擼隊列的3種方法!

    2020-10-21

    動圖演示:手擼堆棧的兩種實現方法!

    2020-09-23

    關注我,每天陪你進步一點點!

    總結

    以上是生活随笔為你收集整理的算法图解:如何用两个栈实现一个队列?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。