栈(Stack)
栈的介绍
- 栈的英文为:Stack
- 栈是一个先入后出(FILO-First In Last Out)的有序列表。
- 栈(stack)是限制线性表中元素的插入和删除只能在线性表的同一端进行的一 种特殊线性表。允许插入和删除的 一端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom)。
- 根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除
- 图解方式说明出栈(pop)和入栈(push)的概念:
栈的应用场景
- 子程序的调用:在跳往子程序前,会先将下个指令的地址存到堆栈中,直到子程序执行完后再将地址取出,以回到原来的程序中。
- 处理递归调用:和子程序的调用类似,只是除了储存下一个指令的地址外,也将参数、区域变量等数据存入堆栈中。
- 表达式的转换[中缀表达式转后缀表达式]与求值。
- 二叉树的遍历。
- 图形的深度优先(depth 一 first)搜索法。
数组实现栈
思路分析
- 使用数组来模拟栈
- 定义一个top来表示栈顶,初始指向为-1
- 入栈操作:当数据加入到栈时,
top++;
stack[top]=data;
- 出栈操作:
int value=stack[top];
top--;
return value;
代码实现:
1. //用数组实现栈 2. public class arraystack { 3. private int[] array;// 数组,数组模拟栈,数据就放在该数组 4. private int top = -1;// top 表示栈顶,初始化为-1 5. private int maxSize; // 栈的大小 6. 7. //构造器 8. public arraystack(int maxSize) { 9. this.maxSize = maxSize; 10. array = new int[this.maxSize]; 11. } 12. 13. //判断栈是否为空 14. public boolean isEmpty() { 15. return top == -1; 16. } 17. 18. //判断栈是否满 19. public boolean isFull() { 20. return top == this.maxSize - 1; 21. } 22. 23. //入栈 24. public void push(int a) { 25. if (isFull()) {//先判断栈是否满 26. System.out.println("push():栈已满,无法添加。。。。"); 27. return; 28. } 29. top++; 30. array[top] = a; 31. } 32. 33. //出栈 34. public int pop() { 35. if (isEmpty()) {//先判断栈是否空 36. throw new RuntimeException("pop():栈已满,无法出栈。。。"); 37. } 38. int i = array[top]; 39. top--; 40. return i; 41. } 42. 43. //遍历 44. public void show() { 45. for (int i = top; i > -1; i--) {//遍历时,需要从栈顶开始显示数据 46. System.out.println(array[i]); 47. } 48. } 49. 50. //获取栈顶元素 51. public int peek() { 52. return array[top]; 53. } 54. }
链表实现栈
代码实现:
- 定义链表:
1. //定义链表 2. public class linkedList<E> { 3. 4. private class Node {//内部类,定义链表中的节点内容 5. private Node next;//表示下一个节点 6. E e;//此节点的值 7. 8. //构造器 9. public Node(E e, Node next) { 10. this.next = next; 11. this.e = e; 12. } 13. 14. //构造器 15. public Node() { 16. this(null, null); 17. } 18. 19. //构造器 20. public Node(E e) { 21. this(e, null); 22. } 23. 24. //重写toString() 25. @Override 26. public String toString() { 27. return "Node{" + 28. "e=" + e + 29. '}'; 30. } 31. } 32. 33. private Node first = new Node();//表示链表的头结点 34. private int size;//表示链表的长度(大小) 35. 36. // 获取链表中的元素个数 37. public int getSize() { 38. return size; 39. } 40. 41. // 返回链表是否为空 42. public boolean isEmpty() { 43. return size == 0; 44. } 45. 46. // 在链表的index( 0 ~ size-1 )位置添加新的元素e 47. public void add(int index, E e) { 48. if (index < 0 || index > size) {//判断index是否合法 49. throw new IllegalArgumentException("add():输入index值有误,添加失败。。。"); 50. } 51. Node temp = first;//头结点不能移动,所以设置辅助节点temp 52. for (int i = 0; i < index; i++) {//将temp节点指向index位置的前一个位置节点 53. temp = temp.next; 54. } 55. Node node = new Node(e, temp.next);//将新元素e创建成node对象,next为temp的下一个节点 56. temp.next = node;//将temp所指节点的next指向node 57. size++; 58. } 59. 60. // 在链表头添加新的元素e 61. public void addAtFirst(E e) { 62. add(0, e); 63. } 64. 65. // 在链表末尾添加新的元素e 66. public void addAtLast(E e) { 67. // add(getSize(),e); 68. add(size, e); 69. } 70. 71. // 获得链表的第index( 0 ~ size-1 )个位置的元素 72. public E get(int index) { 73. if (index < 0 || index >= size) { 74. throw new IllegalArgumentException("get():输入的index非法,获取失败。。。"); 75. } 76. Node temp = first.next; 77. for (int i = 0; i < index; i++) { 78. temp = temp.next; 79. } 80. return temp.e; 81. } 82. 83. // 获得链表的第一个元素 84. public E getFirst() { 85. return get(0); 86. } 87. 88. // 获得链表的最后一个元素 89. public E getLast() { 90. return get(size - 1); 91. } 92. 93. // 修改链表的第index( 0 ~ size-1 )个位置的元素为e 94. public void set(int index, E e) { 95. if (index < 0 || index >= size) { 96. throw new IllegalArgumentException("set():获取元素失败,输入的index值非法!"); 97. } 98. Node temp = first; 99. for (int i = 0; i < index; i++) { 100. temp = temp.next; 101. } 102. temp.e = e; 103. } 104. 105. // 查找链表中是否有元素e 106. public boolean contains(E e) { 107. Node temp = first.next; 108. boolean flag = false; 109. while (temp != null) { 110. if (temp.e.equals(e)) { 111. return true; 112. } 113. temp = temp.next; 114. } 115. return false; 116. } 117. 118. // 从链表中删除index( 0 ~ size-1 )位置的元素, 返回删除的元素 119. public E remove(int index) { 120. if (index < 0 || index >= size) { 121. throw new IllegalArgumentException("remove():获取元素失败,输入的index值非法!"); 122. } 123. Node temp = first; 124. for (int i = 0; i < index; i++) { 125. temp = temp.next; 126. } 127. Node delNode = temp.next; 128. temp.next = delNode.next; 129. size--; 130. return delNode.e; 131. } 132. 133. 134. // 从链表中删除第一个元素(0), 返回删除的元素 135. public E removeFirst() { 136. return remove(0); 137. } 138. 139. // 从链表中删除最后一个元素(size-1), 返回删除的元素 140. public E removeLast() { 141. return remove(size - 1); 142. } 143. 144. // 从链表中删除指定元素e 145. public void removeElement(E e) { 146. Node temp = first; 147. while (temp.next != null) { 148. if (temp.next.e.equals(e)) { 149. temp.next = temp.next.next; 150. size--; 151. return; 152. } 153. temp = temp.next; 154. } 155. System.out.println("removeElemen():没有找到该元素,删除失败。。。"); 156. } 157. 158. //重写toString() 159. @Override 160. public String toString() { 161. StringBuilder stringBuilder = new StringBuilder(); 162. Node temp = first.next; 163. while (temp != null) { 164. if (temp.next == null) { 165. stringBuilder.append(temp.e); 166. } else { 167. stringBuilder.append(temp.e + "->"); 168. } 169. temp = temp.next; 170. } 171. return stringBuilder.toString(); 172. } 173. } 来自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php>
- 用链表定义栈:
1. interface stack<E> { 2. /** 3. * 获取栈的大小 4. */ 5. int getSize(); 6. 7. /** 8. * 栈顶元素出栈 9. */ 10. E pop(); 11. 12. /** 13. * 元素入栈 14. */ 15. void push(E e); 16. 17. /** 18. * 遍历栈元素 19. */ 20. void printAll(); 21. 22. /** 23. * 输出栈顶元素 24. */ 25. E peek(); 26. 27. /** 28. * 判断栈是否为空 29. */ 30. boolean isEmpty(); 31. } 来自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php>
1. //用链表来实现栈 2. class linkedListStack<E> implements stack<E> { 3. private linkedList<E> list; 4. 5. public linkedListStack() { 6. list = new linkedList<>(); 7. } 8. 9. @Override 10. public int getSize() { 11. return list.getSize(); 12. } 13. 14. @Override 15. public E pop() { 16. return list.removeLast(); 17. } 18. 19. @Override 20. public void push(E e) { 21. list.addAtLast(e); 22. } 23. 24. @Override 25. public void printAll() { 26. System.out.println(list.toString()); 27. } 28. 29. @Override 30. public E peek() { 31. E atLast = null; 32. try { 33. atLast = list.getLast(); 34. } catch (Exception e) { 35. System.out.print("栈为空:"); 36. } 37. return atLast; 38. } 39. 40. @Override 41. public boolean isEmpty() { 42. return list.isEmpty(); 43. } 44. 45. } 来自 <http://www.planetb.ca/projects/syntaxHighlighter/popup.php>