棧
1. 棧的定義
棧是限定僅在表尾進行插入和刪除操作的線性表。允許插入、刪除的一端稱為棧頂(top),另一端稱為棧底(bottom),不含任何數據元素的棧稱為空棧。

2. 棧的特點
只能在棧頂進行操作,且訪問結點時依照后進先出(LIFO)的原則。
3. 棧的基本操作
- 初始化——構造一個空的棧
- 入棧——在棧頂位置插入一個新元素
- 出棧——刪除棧頂元素
- 獲取——取棧頂元素
- 判空——判斷當前棧是否為空
- 求長度——求棧中數據元素的個數
- 正序遍歷——依次訪問棧中每個元素並輸出
- 清空——清空棧
4. 棧的實現
- 順序棧——順序存儲方式實現
- 鏈棧——鏈式存儲方式實現
順序棧代碼:
public class SequenceStack<T> {
private final int InitSize = 10; // 初始化長度
private T[] stackArray;
private int top; // top指針,指向棧頂元素的位置
// 默認初始化
public SequenceStack() {
top = -1;
stackArray = (T[]) new Object[InitSize];
}
// 初始化
public SequenceStack(int n) {
if(n < 1) {
System.out.println("初始化長度不合法!");
System.exit(1);
}
top = -1;
stackArray = (T[]) new Object[n];
}
// 棧長度
public int getSize() {
return top + 1;
}
// 判空
public boolean isEmpty() {
return top == -1;
}
// 清空
public void clear() {
top = -1;
stackArray = null;
}
// 遍歷
public void nextOrder() {
if(isEmpty()) {
System.out.println("棧為空!");
System.exit(1);
}
for(int i=top; i>=0; i--) {
System.out.print(stackArray[i] + "\t");
}
System.out.println();
}
// 獲取棧頂元素
public T getTop() {
if(isEmpty()) {
System.out.println("棧為空!不能進行獲取操作!");
return null;
}
return stackArray[top];
}
// 入棧
public void push(T obj) {
if(top + 1 == stackArray.length) {
// 創建一個長度未原來兩倍的新數組
T[] temp = (T[]) new Object[top * 2];
// 將舊數組中的值賦值給新數組
for(int i=top; i>=0; i--) {
temp[i] = stackArray[i];
}
// 將stackArray變量指向新數組
stackArray = temp;
}
stackArray[++top] = obj;
}
// 出棧
public T pop() {
if(isEmpty()) {
System.out.println("棧為空!無法進行出棧操作!");
return null;
}
return stackArray[top--];
}
// 測試
public static void main(String[] args) {
int[] arr = {2, 4, 6, 7, 9};
SequenceStack<Integer> stack = new SequenceStack<>();
System.out.println("入棧:");
for (int i = 0; i < arr.length; i++) {
stack.push(arr[i]);
}
stack.nextOrder();
System.out.println("獲取棧頂元素:");
System.out.println(stack.getTop());
System.out.println("獲取棧長度:");
System.out.println(stack.getSize());
System.out.println("出棧:");
stack.pop();
stack.nextOrder();
System.out.println("9,111入棧:");
stack.push(99);
stack.push(111);
stack.nextOrder();
System.out.println("清空棧:");
stack.clear();
stack.nextOrder();
}
}
測試結果:

鏈棧代碼:

class Node<T> {
T data;
Node<T> next;
public Node(Node<T> next) {
this.next = next;
}
public Node(T data, Node<T> next) {
this.data = data;
this.next = next;
}
}
public class LinkStack<T> {
private int length; // 棧的長度
private Node<T> top; // top指針,指向棧頂元素的位置
// 初始化
public LinkStack() {
top = null;
length = 0;
}
// 棧長度
public int getSize() {
return length;
}
// 判空
public boolean isEmpty() {
return top == null;
}
// 清空
public void clear() {
top = null;
length = 0;
}
// 遍歷輸出
public void nextOrder() {
if(isEmpty()) {
System.out.println("棧為空!");
}
Node<T> p = top;
while(p != null) {
System.out.print(p.data + "\t");
p = p.next;
}
System.out.println();
}
// 入棧
public void push(T obj) {
top = new Node<>(obj, top);
length++;
}
// 獲取棧頂元素
public T getTop() {
if (isEmpty()) {
System.out.println("棧為空!");
return null;
}
return top.data;
}
// 出棧
public T pop() {
if(isEmpty()) {
System.out.println("棧為空!不能進行出棧操作!");
return null;
}
T temp = top.data;
top = top.next;
length--;
return temp;
}
// 測試
public static void main(String[] args) {
LinkStack<Integer> ls = new LinkStack<>();
int[] arr = {12, 14, 16, 18};
// 入棧
for (int i = 0; i < arr.length; i++) {
ls.push(arr[i]);
}
ls.nextOrder(); // 遍歷
System.out.println("出棧后:");
ls.pop(); // 出棧
ls.nextOrder(); // 遍歷
System.out.println("棧長度:" + ls.getSize()); // 棧長度
System.out.println("棧頂元素:" + ls.getTop());
}
}
測試結果:

