供自己鞏固集合知識時寫的筆記,不會對所有的內容都介紹
棧(Stack)是一種后進先出(LIFO:Last In First Out)的數據結構
Stack只有入棧和出棧的操作:
- 把元素壓棧:
push(E); - 把棧頂的元素“彈出”:
pop(); - 取棧頂元素但不彈出:
peek()。
有的人在使用Stack時會發現,Stack沒有單獨的接口。因為有個遺留類名字就叫Stack,出於兼容性考慮,所以沒辦法創建Stack接口。
Stack的作用
Stack在計算機中使用非常廣泛,JVM在處理Java方法調用的時候就會通過棧這種數據結構維護方法調用的層次。例如:
static void main(String[] args) {
foo(123);
}
static String foo(x) {
return "F-" + bar(x + 1);
}
static int bar(int x) {
return x << 2;
}
JVM會創建方法調用棧,每調用一個方法時,先將參數壓棧,然后執行對應的方法;當方法返回時,返回值壓棧,調用方法通過出棧操作獲得方法返回值。
因為方法調用棧有容量限制,嵌套調用過多會造成棧溢出,即引發StackOverflowError:
public class Main {
public static void main(String[] args) {
increase(1);
}
static int increase(int x) {
return increase(x) + 1;
}
}
我們再來看一個Stack的用途:對整數進行進制的轉換就可以利用棧。
例如,我們要把一個int整數12500轉換為十六進制表示的字符串:
先我們准備一個空棧:
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└───┘
然后計算12500÷16=781…4,余數是4,把余數4壓棧:
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ 4 │
└───┘
然后計算781÷16=48…13,余數是13,13的十六進制用字母D表示,把余數D壓棧:
│ │
│ │
│ │
│ │
│ │
│ D │
│ │
│ 4 │
└───┘
然后計算48÷16=3…0,余數是0,把余數0壓棧:
│ │
│ │
│ │
│ 0 │
│ │
│ D │
│ │
│ 4 │
└───┘
最后計算3÷16=0…3,余數是3,把余數3壓棧:
│ │
│ 3 │
│ │
│ 0 │
│ │
│ D │
│ │
│ 4 │
└───┘
當商是0的時候,計算結束,我們把棧的所有元素依次彈出,組成字符串30D4,這就是十進制整數12500的十六進制表示的字符串。
