栈(Stack)
队列是先进先出的数据结构,即FIFO原则,而栈是一种后进先出的数据结构

1、栈的特性
- “先入后出”(FILO)原则 
- 栈是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。只允许进行插入和删除操作,允许插入和删除的一端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom)。 
- 根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除 
2、栈的应用
- 子程序的调用:在跳往子程序前,会先将下个指令的地址存到堆栈中,直到子程序执行完后再将地址取出,以回到原来的程序中。 
- 处理递归调用:和子程序的调用类似,只是除了储存下一个指令的地址外,也将参数、区域变量等数据存入堆栈中。
- 表达式的转换[中缀表达式转后缀表达式]与求值。
- 二叉树的遍历。
- 图形的深度优先(depth一first)搜索法。
- 浏览器的前进和后退功能
3、栈的实现
栈既可以用数组来实现,也可以用链表来实现。用数组实现的栈,我们叫作顺序栈,用链表实现的栈,我们叫作链式栈。
(1)数组模拟栈
思路:
- 使用数组来模拟栈
- 定义一个 top 来表示栈顶,初始化 为 -1
- 入栈(push)的操作,当有数据加入到栈时, top++; stack[top] = data;
- 出栈(pop)的操作, int value = stack[top]; top–, return value
- 当 top = -1; 栈空
- 当 top = maxSize - 1; 栈满
代码实现:
| 12
 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
 95
 96
 97
 98
 99
 100
 
 | import java.util.Scanner;public class ArraryDemo {
 public static void main(String[] args) {
 
 ArrayStack stack = new ArrayStack(4);
 String key = "";
 boolean loop = true;
 Scanner scanner = new Scanner(System.in);
 
 while (loop) {
 System.out.println("show: 显示栈");
 System.out.println("exit: 退出程序");
 System.out.println("push: 入栈");
 System.out.println("pop: 出栈");
 System.out.println("请选择");
 key = scanner.next();
 switch (key) {
 case "show":
 stack.list();
 break;
 case "exit":
 scanner.close();
 loop = false;
 break;
 case "push":
 System.out.println("请输入添加的数据");
 int value = scanner.nextInt();
 stack.push(value);
 break;
 case "pop":
 try {
 int res = stack.pop();
 System.out.println("出栈的数据为" + res);
 } catch (Exception e) {
 System.out.println(e.getMessage());
 }
 break;
 default:
 break;
 }
 
 }
 System.out.println("程序退出");
 }
 }
 
 
 class ArrayStack {
 private int maxSize;
 private int [] stack;
 private int top = -1;
 
 public ArrayStack(int maxSize) {
 this.maxSize = maxSize;
 stack = new int[maxSize];
 }
 
 
 public boolean isFull() {
 return top == maxSize - 1;
 }
 
 
 public boolean isEmpty() {
 return top == -1;
 }
 
 
 public void push(int value) {
 
 if (isFull()) {
 System.out.println("栈满");
 return;
 }
 top++;
 stack[top] = value;
 }
 
 
 public int pop() {
 
 if (isEmpty()) {
 throw new RuntimeException("栈空");
 }
 int value = stack[top];
 top--;
 return value;
 }
 
 
 public void list() {
 if (isEmpty()) {
 System.out.println("栈空");
 return;
 }
 for (int i = top; i >= 0; i--) {
 System.out.println("stack[" + i + "] = " + stack[i]);
 }
 }
 }
 
 | 
(2)链表模拟栈
思路:
- 定义一个节点类Node 
- 定义一个头节点 head 表示栈底 
- 入栈(push)的操作,当有数据加入到栈时, 找到栈尾,temp.next = newNode;; 
- 出栈(pop)的操作,遍历到链表尾部的前一个节点,然后将最后一个节点数据返回,并删除最后一个节点 - int value = temp.next.data; temp.next = null;  return value; 
- 当 head.next == null; 栈空 
代码实现
| 12
 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
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 
 | import java.util.Scanner;public class LinkedListStackDemo {
 public static void main(String[] args) {
 
 LinkedListStack stack = new LinkedListStack();
 String key = "";
 boolean loop = true;
 Scanner scanner = new Scanner(System.in);
 
 while (loop) {
 System.out.println("show: 显示栈");
 System.out.println("exit: 退出程序");
 System.out.println("push: 入栈");
 System.out.println("pop: 出栈");
 System.out.println("请选择");
 key = scanner.next();
 switch (key) {
 case "show":
 stack.list();
 break;
 case "exit":
 scanner.close();
 loop = false;
 break;
 case "push":
 System.out.println("请输入添加的数据");
 int value = scanner.nextInt();
 stack.push(value);
 break;
 case "pop":
 try {
 int res = stack.pop();
 System.out.println("出栈的数据为" + res);
 } catch (Exception e) {
 System.out.println(e.getMessage());
 }
 break;
 default:
 break;
 }
 }
 System.out.println("程序退出");
 }
 }
 
 
 class LinkedListStack {
 
 private Node head = new Node(0);
 
 
 public boolean isEmpty() {
 return head.next == null;
 }
 
 
 public void push(int data) {
 Node newNode = new Node(data);
 
 Node temp = head;
 while (true) {
 
 if (temp.next == null) {
 break;
 }
 
 temp = temp.next;
 }
 temp.next = newNode;
 }
 
 
 public int pop() {
 if (isEmpty()) {
 throw new RuntimeException("栈空");
 }
 Node temp = head;
 while (true) {
 
 if (temp.next.next == null) {
 break;
 }
 
 temp = temp.next;
 }
 
 
 int value = temp.next.data;
 temp.next = null;
 return value;
 }
 
 
 public void list() {
 
 if (isEmpty()) {
 System.out.println("链表为空");
 return;
 }
 
 Node temp = head.next;
 while (true) {
 if (temp == null) {
 break;
 }
 
 System.out.println(temp.data);
 
 temp = temp.next;
 }
 }
 }
 
 
 class Node {
 public int data;
 public Node next;
 public Node(int data) {
 this.data = data;
 }
 }
 
 |