下压栈(简称栈)是一种基于后进先出(LILO)策略的集合类型。可以使用数组链表实现。

API

成员函数(Item 是泛型变量) 功能
Stack() 创建一个空栈
void push(Item item) 添加一个元素
Item pop() 删除最近添加的元素
boolean isEmpty() 栈是否为空
int size() 栈中的元素数量
peek() 查看最近添加的元素(不删除)

实现

两种实现都支持 forEach 迭代。

数组实现

  1. import java.util.Iterator;
  2. import java.util.NoSuchElementException;
  3. import java.util.Random;
  4. public class ResizingArrayStack<Item> implements Iterable<Item> {
  5. // 数组默认初始化大小
  6. private static final int INIT_CAPACITY = 8;
  7. // 用于存储元素的数组
  8. private Item[] a;
  9. // 当前栈的元素数量
  10. private int n;
  11. public ResizingArrayStack() {
  12. a = (Item[]) new Object[INIT_CAPACITY];
  13. n = 0;
  14. }
  15. /**
  16. * 判断是否为空栈
  17. *
  18. * @return 如果为空返回 true,否则 false
  19. */
  20. public boolean isEmpty() {
  21. return n == 0;
  22. }
  23. /**
  24. * 调整数组大小
  25. *
  26. * @param capacity
  27. */
  28. private void resize(int capacity) {
  29. assert capacity >= n;
  30. Item[] copy = (Item[]) new Object[capacity];
  31. if (n >= 0) System.arraycopy(a, 0, copy, 0, n);
  32. a = copy;
  33. }
  34. /**
  35. * 添加新元素
  36. *
  37. * @param item
  38. */
  39. public void push(Item item) {
  40. if (n == a.length) resize(2 * a.length);
  41. a[n++] = item;
  42. }
  43. /**
  44. * 当前栈的元素数量
  45. *
  46. * @return 元素数量
  47. */
  48. public int size() {
  49. return n;
  50. }
  51. /**
  52. * 删除并返回最近添加的元素
  53. *
  54. * @return 最近添加的元素
  55. */
  56. public Item pop() {
  57. if (isEmpty()) throw new NoSuchElementException("Stack underflow");
  58. Item item = a[n - 1];
  59. a[n - 1] = null;
  60. n--;
  61. if (n > 0 && n == a.length / 4) resize(a.length / 2);
  62. return item;
  63. }
  64. /**
  65. * 查看最新添加的元素(不删除)
  66. *
  67. * @return 最近添加的元素
  68. */
  69. public Item peek() {
  70. if (isEmpty()) throw new NoSuchElementException("stack underflow");
  71. return a[n - 1];
  72. }
  73. /**
  74. * 转化为字符串
  75. *
  76. * @return 字符串
  77. */
  78. public String toString() {
  79. StringBuilder s = new StringBuilder();
  80. for (Item item : this) {
  81. s.append(item).append(" ");
  82. }
  83. return s.toString();
  84. }
  85. @Override
  86. public Iterator<Item> iterator() {
  87. return new ReverseArrayIterator();
  88. }
  89. /**
  90. * 内部类用于 forEach 遍历
  91. */
  92. private class ReverseArrayIterator implements Iterator<Item> {
  93. private int i;
  94. public ReverseArrayIterator() {
  95. i = n - 1;
  96. }
  97. @Override
  98. public boolean hasNext() {
  99. return i >= 0;
  100. }
  101. public void remove() {
  102. throw new UnsupportedOperationException();
  103. }
  104. @Override
  105. public Item next() {
  106. if (!hasNext()) throw new NoSuchElementException();
  107. return a[i--];
  108. }
  109. }
  110. public static void main(String[] args) {
  111. ResizingArrayStack<String> stack = new ResizingArrayStack<>();
  112. for (int i = 0; i < 10; i++) {
  113. // generator random string
  114. int leftLimit = 97; // letter 'a'
  115. int rightLimit = 122; // letter 'z'
  116. int targetStringLength = 3;
  117. Random random = new Random();
  118. String generatedString = random.ints(leftLimit, rightLimit + 1)
  119. .limit(targetStringLength)
  120. .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
  121. .toString();
  122. stack.push(generatedString);
  123. }
  124. // print
  125. for (String s : stack) {
  126. System.out.println("str: " + s);
  127. }
  128. }
  129. }

链表实现

  1. mport java.util.Iterator;
  2. import java.util.NoSuchElementException;
  3. import java.util.Random;
  4. public class LinkedStack<Item> implements Iterable<Item> {
  5. private Node first; // 栈顶
  6. private int N; // 栈的元素数量
  7. /**
  8. * node 内部类
  9. */
  10. private class Node {
  11. Item item;
  12. Node next;
  13. }
  14. /**
  15. * 是否空栈
  16. *
  17. * @return 为空返回 true,否者返回 false
  18. */
  19. public boolean isEmpty() {
  20. return first == null;
  21. }
  22. /**
  23. * 当前栈的元素数量
  24. *
  25. * @return 元素数量
  26. */
  27. public int size() {
  28. return N;
  29. }
  30. /**
  31. * 添加一个新的元素
  32. *
  33. * @param item
  34. */
  35. public void push(Item item) {
  36. Node oldFirst = first;
  37. first = new Node();
  38. first.item = item;
  39. first.next = oldFirst;
  40. N++;
  41. }
  42. /**
  43. * 删除一个最近添加的元素
  44. *
  45. * @return 最近添加的元素
  46. */
  47. public Item pop() {
  48. Item item = first.item;
  49. first = first.next;
  50. N--;
  51. return item;
  52. }
  53. /**
  54. * 返回最近添加的元素(不删除)
  55. *
  56. * @return 最近添加的元素
  57. */
  58. public Item peek() {
  59. if (isEmpty()) throw new NoSuchElementException("Stack underflow");
  60. return first.item;
  61. }
  62. /**
  63. * 转化为字符串
  64. *
  65. * @return 字符串
  66. */
  67. public String toString() {
  68. StringBuilder s = new StringBuilder();
  69. for (Item item : this) {
  70. s.append(item).append(" ");
  71. }
  72. return s.toString();
  73. }
  74. /**
  75. * 检测内部变量
  76. *
  77. * @return
  78. */
  79. private boolean check() {
  80. if (N < 0) {
  81. return false;
  82. }
  83. if (N == 0) {
  84. if (first != null) return false;
  85. } else if (N == 1) {
  86. if (first == null) return false;
  87. if (first.next != null) return false;
  88. } else {
  89. if (first == null) return false;
  90. if (first.next == null) return false;
  91. }
  92. int numberOfNodes = 0;
  93. for (Node x = first; x != null && numberOfNodes <= N; x = x.next) {
  94. numberOfNodes++;
  95. }
  96. return numberOfNodes == N;
  97. }
  98. @Override
  99. public Iterator<Item> iterator() {
  100. return new LinkedIterator();
  101. }
  102. private class LinkedIterator implements Iterator<Item> {
  103. private Node current = first;
  104. public boolean hasNext() {
  105. return current != null;
  106. }
  107. public void remove() {
  108. throw new UnsupportedOperationException();
  109. }
  110. public Item next() {
  111. if (!hasNext()) throw new NoSuchElementException();
  112. Item item = current.item;
  113. current = current.next;
  114. return item;
  115. }
  116. }
  117. public static void main(String[] args) {
  118. LinkedStack<String> stack = new LinkedStack<>();
  119. for (int i = 0; i < 10; i++) {
  120. // generator random string
  121. int leftLimit = 97; // letter 'a'
  122. int rightLimit = 122; // letter 'z'
  123. int targetStringLength = 3;
  124. Random random = new Random();
  125. String generatedString = random.ints(leftLimit, rightLimit + 1)
  126. .limit(targetStringLength)
  127. .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
  128. .toString();
  129. stack.push(generatedString);
  130. }
  131. // print
  132. for (String s : stack) {
  133. System.out.println("str: " + s);
  134. }
  135. }
  136. }

参考: