上一篇講過隊列(queue),隊列就像是居民樓里的垃圾管道,從樓道的垃圾管道的入口處將垃圾扔進去,清潔工會從一樓垃圾管道的出口處將垃圾拿走。每一層的垃圾通道入口與一樓的垃圾管道出口之間都形成了一個隊列,先被扔進垃圾道里的垃圾會先到達垃圾通道的出口,即:先進先出。
棧是一種更簡單的數據結構,如果隊列是垃圾通道,那棧就是垃圾桶,先扔進垃圾桶的垃圾都被壓桶底了,反而是后仍進去的垃圾會先被倒出來。這種后進先出的數據結構,就是——棧(stack)。
隊列的三要素是隊伍,隊頭,隊尾。
在PowerShell中可以用一個動態數組表示隊伍,用兩個變量來表示隊頭和隊尾之於數組中的位置。
隊列(垃圾道)有兩頭,數據從一頭進,另一頭出。進的那頭叫隊尾,出的那頭叫隊頭。
棧(垃圾桶)只有一頭,從哪頭進就從哪頭出,進的那頭叫頂(垃圾桶都是立着放)。
在PowerShell中可以用一個動態數組來表示棧,棧頂之於數組的位置就用一個變量來記錄。
$stack = New-Object System.Collections.ArrayList #Create a stack of numbers. $flag = $true while($flag) { $input = Read-Host "Put a number into the stack" $stack.Add([int] $input) $choice = Read-Host "Press 'c' to continue, any other key to quit" if($choice -ne 'c') { $flag = $false } } $top = $stack.count-1 $stack_top = $stack[$top] #Show the top number of this stack. Write-Host "The top of the stack is:" -ForegroundColor green Write-Host $stack_top -ForegroundColor green
以上這段代碼簡述了棧的創建和棧頂元素的查看方法。
現在來舉個現實世界中的例子,你立刻就會明白什么是棧——發撲克牌。

首先創建一套撲克牌:
#Create a set of pokers. $pokers = New-Object System.Collections.ArrayList $pokerModel = @{"pokers"="2,3,4,5,6,7,8,9,10,J,Q,K,A,SmallKing,BigKing";"colors"="spade,heart,club,diamond"} $pokerEles = $pokerModel.Item("pokers").Split(",") $pokerColors = $pokerModel.Item("colors").Split(",") foreach($pokerEle in $pokerEles) { if(($pokerEle -eq "SmallKing") -or ($pokerEle -eq "BigKing")) { $pokers.Add($pokerEle) } else { foreach($color in $pokerColors) { $newPoker = $color + "_" + $pokerEle $pokers.Add($newPoker) } } }
然后對這幅撲克進行洗牌(將第一張牌隨機放入整副牌中,重復10000次):
#Shuffle. for($i=0;$i -le 10000;$i++) { $randomPlace = Get-Random -min 0 -max $pokers.count $selectedPoker = $pokers[0] $pokers.RemoveAt(0) $pokers.Insert($randomPlace, $selectedPoker) }
然后我們把洗好的牌放進“棧”中(發牌器就是棧),像下圖這個樣子。然后開始發牌(每次發牌都是從棧頂pop出一張)——

#Push the cards into the stack. $myStack = new-object System.Collections.Stack foreach($poker in $pokers) { $myStack.Push($poker) } #Start the deal. Write-Host "---Start dealing---" -ForegroundColor green $flag = $true while($flag) { $myStack.Pop() $choice = Read-Host "Press 'c' to continue, any other key to quit" if($choice -ne 'c') { $flag = $false } else { Write-Host "---Continue dealing---" -ForegroundColor yellow } }
運行結果如下:
到此,一個發紙牌的過程就完成了,而這個發牌器就是棧,裝牌的過程就是入棧的過程,發牌的過程就是出棧的過程。
