天天看點

算法:棧和隊列題目集合(一)

棧和隊列是算法的一個基本的知識點之一。這篇文章主要介紹三道有關棧和隊列的算法題。因為篇幅所限,隻介紹push和pop這兩種方法的實作:1.用棧實作隊列 2.用隊列實作棧 3.循環隊列的實作

前言

棧和隊列是算法的一個基本的知識點之一。這篇文章主要介紹三道有關棧和隊列的算法題。因為篇幅所限,隻介紹push和pop這兩種方法的實作

用棧實作隊列

用隊列實作棧

循環隊列的實作

入隊列的功能我們可以用棧的入棧的功能替代。但問題在于出隊列的功能怎麼實作。

這裡有一個問題,就是棧是後入先出的,隊列是先進先出的,兩者出入的方式不一樣。

那麼怎麼實作方向的一緻呢? 我們可以使用兩個棧,一個棧用于輸入,一個棧用于輸出。當發現輸出棧為空的時候,把排列的資料從輸入棧一個個彈出,“倒入”到 輸出棧中,這樣的話,資料排列的方向就剛好被逆轉過來了,原本在輸入棧中處于棧底的資料被置換到輸出棧的棧頂,這時候對它出棧也就同時完成了隊列的出列的功能。

下面是具體的圖示

1.入隊列操作: 等同于對入隊列進行入棧操作,圖示如下

算法:棧和隊列題目集合(一)

2.出隊列操作: 判斷當輸出棧為空時,先把輸入棧的資料依次彈出并加入到輸出棧中

算法:棧和隊列題目集合(一)

步驟1

算法:棧和隊列題目集合(一)

步驟2

對輸出棧棧頂進行出棧操作,即可完成出隊列功能

算法:棧和隊列題目集合(一)

步驟3

具體代碼

這裡同樣有兩個功能需要我們實作,分别是入棧功能和出棧功能

入棧功能

我們可以用入棧操作模拟實作

算法:棧和隊列題目集合(一)

出棧功能

我們又來到了關鍵功能,這時候你能猜到,我們又需要用到兩個隊列去實作這個出棧功能了

但問題在于,我們還能否通過講資料從一個隊列“倒”到另一個隊列的方式逆轉資料方向呢? 這是不行的,因為隊列先入先出的特性,導緻分割後隊列的出入方向仍然是不變的。是以我們要換個思路:

一個元素入隊列了,我們接下來希望這個隊列像棧一樣通過pop把它直接彈出來,但是前面還有很多個元素排着隊呢,這時我們想,隻要把前面排隊的所有元素先出列到另外一個輔助隊列裡面去,接下來不就可以直接把這個元素踢出隊列進而模拟出棧了嗎?

算法:棧和隊列題目集合(一)
算法:棧和隊列題目集合(一)

當然完成pop操作後我們還要做一件事情,就是輔助隊列和主隊列互換,以讓未來還能按同樣的流程再來一次。

算法:棧和隊列題目集合(一)

設計循環隊列的原因

對于普通的單向隊列,在入隊列和出隊列的時候可能會遇到一種“隊列假滿”的現象,導緻空間的浪費如下圖所示

算法:棧和隊列題目集合(一)

是以我們要做的,就是通過設定頭部(front)和尾部(rear)兩個指針來區分隊列的“滿的部分”和“空的部分”,并且允許在填充到數組末尾的時候,能通過回到數組的頭部這種循環的方式繼續填充數組,進而提高數組空間的使用率。

算法:棧和隊列題目集合(一)

怎麼實作從尾部到頭部的循環呢? 我們可以通過取餘運算符實作,因為當 i = 數組長度- 1的時候,(i + 1) % 數組長度 = 0,也就是說這個時候指針又從尾部回到了數組的頭部

算法:棧和隊列題目集合(一)

我叫彭湖灣,請叫我胖灣

繼續閱讀