坐在馬桶上看演算法(6):棧

啊哈磊發表於2016-05-11

上一節中我們學習了佇列,它是一種先進先出的資料結構。還有一種是後進先出的資料結構它叫做棧。棧限定只能在一端進行插入和刪除操作。比如說有一個小桶,小桶的直徑只能放一個小球,我們現在向小桶內依次放入2號、1號、3號小球。假如你現在需要拿出2號小球,那就必須先將3號小球拿出,再拿出1號小球,最後才能將2號小球拿出來。在剛才取小球的過程中,我們最先放進去的小球最後才能拿出來,而最後放進去的小球卻可以最先拿出來。這就是後進先出,也可以稱為先進後出。

 

stack

我們生活中還有很多這樣的例子,比如我們在吃桶裝薯片的時候,要想吃掉最後一片,就必須把前面的全部吃完(貌似現在的桶裝薯片為了減少分量,在桶裡面增加了一個透明的抽屜);再比如我們瀏覽網頁時候需要退回到之前的某個網頁,我們需要一步步的點選後退鍵。還有手-槍的彈夾,在裝子彈的時候,最後裝的一發子彈,是被第一個打出去的。棧的實現也很簡單,只需要一個一維陣列和一個指向棧頂的變數top就可以了。我們通過變數top來對棧進行插入和刪除操作。

這種特殊的資料結構棧究竟有哪些作用呢?我們來看一個例子。“xyzyx”是一個迴文字串,所謂迴文字串就是指正讀反讀均相同的字元序列,如“席主席”、“記書記”、“aha”和“ahaha”均是迴文,但“ahah”不是迴文。通過棧這個資料結構我們將很容易判斷一個字串是否為迴文。

首先我們需要讀取這行字串,並求出這個字串的長度。

如果一個字串是迴文的話,那麼它必須是中間對稱,我們需要求這個字串的 中點,即:

接下來就輪到棧出場了。

我們先將mid之前的部分的字元全部入棧。因為這裡的棧是用來儲存字元的,所以這裡用來實現棧的陣列型別是字元陣列即char s[101]; 初始化棧很簡單,top=0;就可以了。入棧的操作是top++;s[top]=x; (假設需要入棧的字元儲存暫存在字元變數x中)其實可以簡寫為s[++top]=x;

現在我們就來將mid之前的字元依次全部入棧。這裡迴圈要0開始,因為剛才讀取字串使用了gets()函式,讀取的第一個字元儲存在s[0]中,隨後一個字元儲存在s[len-1]中。

接下來進入判斷迴文的關鍵步驟。將當前棧中的字元依次出棧,看看是否能與mid之後的字元一一匹配,如果都能匹配則說明這個字串是迴文字串,否則這個字串就不是迴文字串。

最後如果top的值為0,就說明棧內所有的字元都被一一匹配了,那麼這個字串就是迴文字串。完整的程式碼如下。

可以輸入以下資料進行驗證

執行結果是

棧還可以用來進行驗證括號的匹配。比如輸入一行只包含“()[]{}”的字串,形如“([{}()])”或者“{()[]{}}”請判斷是否可以正確匹配。顯然上面兩個例子都是可以正確匹配的。“([)]”是不能匹配的。有興趣的同學可以自己動手來試一試。

堆疊最早由Alan M. Turing(艾倫·圖靈)於1946年提出,當時為了解決子程式的呼叫和返回。艾倫·圖靈這個大帥哥可是個大牛人,圖靈獎就是以他的名字命名的。如果你對他感興趣不妨去讀一讀他的傳記《艾倫圖靈傳:如謎的解謎者》。

相關文章