java資料結構-棧
1、棧的基本概念
棧(英語:stack)又稱為堆棧或堆疊,棧作為一種資料結構,是一種只能在一端進行插入和刪除操作的特殊線性表。它按照先進後出的原則儲存資料,先進入的資料被壓入棧底,最後的資料在棧頂,需要讀資料的時候從棧頂開始彈出資料(最後一個數據被第一個讀出來)。棧具有記憶作用,對棧的插入與刪除操作中,不需要改變棧底指標。
棧是允許在同一端進行插入和刪除操作的特殊線性表。允許進行插入和刪除操作的一端稱為棧頂(top),另一端為棧底(bottom);棧底固定,而棧頂浮動;棧中元素個數為零時稱為空棧。插入一般稱為進棧(PUSH),刪除則稱為退棧(POP)。
由於堆疊資料結構只允許在一端進行操作,因而按照後進先出(LIFO, Last In First Out)的原理運作。棧也稱為後進先出表。
這裡以羽毛球筒為例,羽毛球筒就是一個棧,剛開始羽毛球筒是空的,也就是空棧,然後我們一個一個放入羽毛球,也就是一個一個push進棧,當我們需要使用羽毛球的時候,從筒裡面拿,也就是pop出棧,但是第一個拿到的羽毛球是我們最後放進去的
2、Java模擬簡單的順序棧實現
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
|
測試:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
結果:
這個棧是用陣列實現的,內部定義了一個數組,一個表示最大容量的值以及一個指向棧頂元素的top變數。構造方法根據引數規定的容量建立一個新棧,push()方法是向棧中壓入元素,指向棧頂的變數top加一,使它指向原頂端資料項上面的一個位置,並在這個位置上儲存一個數據。pop()方法返回top變數指向的元素,然後將top變數減一,便移除了資料項。要知道 top 變數指向的始終是棧頂的元素。
產生的問題:
①、上面棧的實現初始化容量之後,後面是不能進行擴容的(雖然棧不是用來儲存大量資料的),如果說後期資料量超過初始容量之後怎麼辦?(自動擴容)
②、我們是用陣列實現棧,在定義陣列型別的時候,也就規定了儲存在棧中的資料型別,那麼同一個棧能不能儲存不同型別的資料呢?(宣告為Object)
③、棧需要初始化容量,而且陣列實現的棧元素都是連續儲存的,那麼能不能不初始化容量呢?(改為由連結串列實現)
3、增強功能版棧
對於上面出現的問題,第一個能自動擴容,第二個能儲存各種不同型別的資料,解決辦法如下:(第三個在講連結串列的時候在介紹)
這個模擬的棧在JDK原始碼中,大家可以參考 Stack 類的實現。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
|
測試:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
結果:
4、利用棧實現字串逆序
我們知道棧是後進先出,我們可以將一個字串分隔為單個的字元,然後將字元一個一個push()進棧,在一個一個pop()出棧就是逆序顯示了。如下:
將 字串“how are you” 反轉!!!
ps:這裡我們是用上面自定的棧來實現的,大家可以將ArrayStack替換為JDK自帶的棧類Stack試試
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
結果:
5、利用棧判斷分隔符是否匹配
寫過xml標籤或者html標籤的,我們都知道<必須和最近的>進行匹配,[ 也必須和最近的 ] 進行匹配。
比如:<abc[123]abc>這是符號相匹配的,如果是 <abc[123>abc] 那就是不匹配的。
對於 12<a[b{c}]>,我們分析在棧中的資料:遇到匹配正確的就消除
最後棧中的內容為空則匹配成功,否則匹配失敗!!!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
6、總結
根據棧後進先出的特性,我們實現了單詞逆序以及分隔符匹配。所以其實棧是一個概念上的工具,具體能實現什麼功能可以由我們去想象。棧通過提供限制性的訪問方法push()和pop(),使得程式不容易出錯。
對於棧的實現,我們稍微分析就知道,資料入棧和出棧的時間複雜度都為O(1),也就是說棧操作所耗的時間不依賴棧中資料項的個數,因此操作時間很短。而且需要注意的是棧不需要比較和移動操作,我們不要畫蛇添足