如何使用数组实现栈和队列?

Python中的list有如下的两个方法:

  • appned(x):在列表的末尾添加元素
  • pop(index = -1):从列表中弹出指定索引的元素,默认为弹出列表的末尾元素

因此,我们使用list可以很方法的实现栈和队列,废话不多说,直接上代码:

数组实现栈:

  • python实现

    1. class Stack:
    2. def __init__(self, array = None):
    3. super().__init__()
    4. self.array = array
    5. # 入栈
    6. def push(self, x):
    7. self.array.append(x)
    8. # 出栈
    9. def pop(self,):
    10. if len(self.array) == 0:
    11. return
    12. return self.array.pop()
    13. # 取栈顶元素
    14. def top(self,):
    15. if len(self.array) == 0:
    16. return
    17. return self.array[-1]
    18. # 判空
    19. def isEmpty(self,):
    20. return True if self.array == [] else False
  • Java实现
    Java中的数组并没有python中list类似的方法,因此需要设置一个变量size来表示当前数组中的元素个数,以及方便进行栈顶元素的获取。 ```java public class ArrayToStack {

    public static class Array2Stack{

    1. private T[] array;
    2. private int size;
    3. public Array2Stack() {
    4. }
    5. public Array2Stack(T[] array) {
    6. this.array = array;
    7. this.size = 0;
    8. }
  1. // 入栈
  2. public void push(T x){
  3. if (this.size == this.array.length){
  4. throw new ArrayIndexOutOfBoundsException("the stack is full!");
  5. }
  6. this.array[size++] = x;
  7. }
  8. // 出栈
  9. public T pop(){
  10. if (isEmpty()){
  11. throw new ArrayIndexOutOfBoundsException("the stack is empty");
  12. }
  13. return this.array[--size];
  14. }
  15. // 取栈顶元素
  16. public T top(){
  17. if (isEmpty()){
  18. return null;
  19. }
  20. return this.array[size];
  21. }
  22. // 判空
  23. public boolean isEmpty(){
  24. boolean flag = this.size == 0 ? true : false;
  25. return flag;
  26. }

}

public static void main(String[] args) { int size = 10; Integer [] array = new Integer[size]; Array2Stack stack = new Array2Stack<>(array);

  1. // 入栈
  2. stack.push(1);
  3. stack.push(2);
  4. stack.push(3);
  5. // 出栈
  6. while(!stack.isEmpty()){
  7. System.out.println(stack.pop()); // 3, 2, 1
  8. }
  9. String[] arr = new String[size];
  10. Array2Stack<String> stack1 = new Array2Stack<>(arr);
  11. stack1.push("Forlogen");
  12. stack1.push("kobe");
  13. while(!stack1.isEmpty()){
  14. System.out.println(stack1.pop()); // kobe, Forlogen
  15. }

} }

  1. <a name="76b1e409"></a>
  2. #### 数组实现队列
  3. -
  4. python实现:
  5. ```python
  6. class Queue:
  7. def __init__(self, array = None):
  8. super().__init__()
  9. self.array = array
  10. # 入队
  11. def enqueue(self, x):
  12. self.array.append(x)
  13. # 出队
  14. def dequeue(self):
  15. if len(self.array) == 0:
  16. return
  17. return self.array.pop(0)
  18. # 判空
  19. def isEmpty(self,):
  20. return True if self.array == [] else False
  • Java实现
    使用数组实现队列除了需要变量size来表示当前数组中的元素个数外,还需要firstlast来表示队头元素和队尾元素的位置,将数组循环使用。 ```java package DataStructure;

import java.util.Arrays;

public class ArrayToQueue{ private T[] array; private int size = 0; private int first = 0; private int last = 0;

  1. public ArrayToQueue() {
  2. }
  3. public ArrayToQueue(T[] array) {
  4. if (size < 0){
  5. throw new IllegalArgumentException("the size is less than 0!");
  6. }
  7. this.array = array;
  8. }
  9. // 入队
  10. public void enqueue(T x){
  11. if (this.size == this.array.length){
  12. throw new ArrayIndexOutOfBoundsException("the queue is full!");
  13. }
  14. size++;
  15. this.array[this.last] = x;
  16. last = last == this.array.length - 1 ? 0 : last + 1;
  17. }
  18. // 出队
  19. public T dequeue(){
  20. if (isEmpty()){
  21. throw new ArrayIndexOutOfBoundsException("the queue is empty!");
  22. }
  23. size--;
  24. int tmp = first;
  25. first = first == this.array.length - 1 ? 0: first + 1;
  26. return this.array[tmp];
  27. }
  28. public boolean isEmpty(){
  29. boolean flag = this.size == 0 ? true : false;
  30. return flag;
  31. }
  32. public static void main(String[] args) {
  33. int size = 10;
  34. Integer[] array = new Integer[size];
  35. ArrayToQueue<Integer> queue = new ArrayToQueue<>(array);
  36. // 入队
  37. queue.enqueue(1);
  38. queue.enqueue(2);
  39. queue.enqueue(3);
  40. System.out.println(Arrays.toString(array));
  41. while(!queue.isEmpty()){
  42. System.out.println(queue.dequeue()); // 1, 2,3
  43. }
  44. }

}

  1. ---
  2. <a name="5fac658e"></a>
  3. ### 如何构建获取最小元素的栈
  4. -
  5. **思路1**:`array``mins`分别存储入栈的元素和当前已入栈元素中最小的元素
  6. - 入栈:如果此时栈为空,则将元素同时压入两个数组中;如果此时栈不为空且入栈的元素小于`mins`的末尾元素,则同时压入两个数组;如果此时栈不为空但入栈的元素大于`mins`的末尾元素,则只将入栈元素压入`array`
  7. - 出栈:同样需要判断当前`array`的栈顶元素和`mins`末尾元素的关系,从而来判断是否需要同时出栈,还是只对`array`执行出栈操作
  8. ```python
  9. class MinStack:
  10. def __init__(self, array = None):
  11. super().__init__()
  12. self.array = array
  13. self.mins = []
  14. # 入栈
  15. def push(self, x):
  16. if len(self.mins) == 0:
  17. self.array.append(x)
  18. self.mins.append(x)
  19. else:
  20. if x < self.mins[-1]:
  21. self.array.append(x)
  22. self.mins.append(x)
  23. else:
  24. self.array.append(x)
  25. # 出栈
  26. def pop(self,):
  27. if len(self.array) == 0:
  28. return
  29. elif self.top() == self.mins[-1]:
  30. self.mins.pop()
  31. return self.array.pop()
  32. else:
  33. return self.array.pop()
  34. # 获取栈中的最小元素
  35. def getMin(self, ):
  36. if len(self.array) == 0:
  37. return
  38. return self.mins[-1]
  39. # 取栈顶元素
  40. def top(self,):
  41. if len(self.array) == 0:
  42. return
  43. return self.array[-1]
  • 思路2: 同样使用arraymins来存储入栈的元素和当前栈中最小的元素,不同之处在于入栈和出栈更为简单,假设当前栈不为空:

    • 入栈:如果入栈元素x大于等于mins的栈顶元素,则将x压入array中,而mins重新压入它当前的栈顶元素
    • 出栈:arraymins同时出栈 ```python class MinStack: def init(self, array = None): super().init() self.array = array self.mins = []

      入栈

      def push(self, x): if len(self.mins) == 0:

      1. self.array.append(x)
      2. self.mins.append(x)

      else:

      1. if x < self.mins[-1]:
      2. self.array.append(x)
      3. self.mins.append(x)
      4. else:
      5. self.mins.append(self.mins[-1])
      6. self.array.append(x)

      出栈

      def pop(self,): if len(self.array) == 0:

      1. return

      self.mins.pop() return self.array.pop()

  1. # 获取栈中的最小元素
  2. def getMin(self, ):
  3. if len(self.array) == 0:
  4. return
  5. return self.mins[-1]
  6. # 取栈顶元素
  7. def top(self,):
  8. if len(self.array) == 0:
  9. return
  10. return self.array[-1]
  1. ---
  2. <a name="f2a0b1f3"></a>
  3. ### 如何使用队列实现栈?
  4. -
  5. python实现:
  6. <br />Python`collections`模块中的`deque`为一个双端队列,使用其中的`append()`入栈和使用`pop()`出栈,实现代码:
  7. ```python
  8. from collections import deque
  9. class Stack:
  10. def __init__(self, array = None):
  11. super().__init__()
  12. self.queue = deque(array)
  13. # 入栈
  14. def push(self, x):
  15. self.queue.append(x)
  16. # 出栈
  17. def pop(self,):
  18. if (list(self.queue)) == 0:
  19. return
  20. return self.queue.pop()
  21. # 取栈顶元素
  22. def top(self,):
  23. if (list(self.queue)) == 0:
  24. return
  25. return list(self.queue)[-1]
  26. # 判空
  27. def isEmpty(self, ):
  28. return True if (list(self.queue)) == 0 else False
  • Java 实现: ```java import java.util.LinkedList; import java.util.Queue;

public class QueueToStack{ private Queue queue1; private Queue queue2;

  1. public QueueToStack(Queue<T> queue1, Queue<T> queue2) {
  2. this.queue1 = queue1;
  3. this.queue2 = queue2;
  4. }
  5. // 入栈
  6. public void push(T x){
  7. this.queue1.add(x);
  8. }
  9. // 出栈
  10. public T pop(){
  11. if (queue1.isEmpty()){
  12. throw new RuntimeException("stack is empty");
  13. }
  14. while (this.queue1.size() > 1){
  15. this.queue2.add(this.queue1.poll());
  16. }
  17. T res = this.queue1.poll();
  18. swap();
  19. return res;
  20. }
  21. // 交换引用
  22. private void swap() {
  23. Queue<T> tmp = this.queue2;
  24. queue2 = queue1;
  25. queue1 = tmp;
  26. }
  27. // 返回栈顶元素
  28. public T top(){
  29. if (queue1.isEmpty()){
  30. throw new RuntimeException("stack is empty");
  31. }
  32. while (this.queue1.size() > 1){
  33. this.queue2.add(this.queue1.poll());
  34. }
  35. T res = this.queue1.poll();
  36. this.queue2.add(res);
  37. swap();
  38. return res;
  39. }
  40. // 判空
  41. public boolean isEmpty(){
  42. if (this.queue1.isEmpty() && this.queue2.isEmpty()){
  43. return true;
  44. } else{
  45. return false;
  46. }
  47. }
  48. @Override
  49. public String toString() {
  50. return "QueueToStack{" +
  51. "queue1=" + queue1 +
  52. ", queue2=" + queue2 +
  53. '}';
  54. }
  55. public static void main(String[] args) {
  56. Queue<Integer> queue1 = new LinkedList<>();
  57. Queue<Integer> queue2 = new LinkedList<>();
  58. QueueToStack<Integer> stack = new QueueToStack<>(queue1, queue2);
  59. stack.push(1);
  60. stack.push(2);
  61. stack.push(3);
  62. stack.push(4);
  63. stack.push(5);
  64. System.out.println(stack); // QueueToStack{queue1=[1, 2, 3, 4, 5], queue2=[]}
  65. System.out.println(stack.top()); // 5
  66. stack.pop();
  67. System.out.println(stack); // QueueToStack{queue1=[1, 2, 3, 4], queue2=[]}
  68. }

}

  1. ---
  2. <a name="33315cdf"></a>
  3. ### 如何使用栈构建队列?
  4. -
  5. python实现:<br />
  6. 队列是一种先进先出的数据结构,而栈是一种后见先出的数据结构。因此需用一个栈`stack1`做入队,另一个`stack2`做出队。如果`stack2`不为空则直接弹出,否则需将`stack1`中的全部元素先压入`stack2`再从`stack2`中出栈。
  7. ```python
  8. class Queue:
  9. def __init__(self):
  10. super().__init__()
  11. self.stack1 = []
  12. self.stack2 = []
  13. # 入栈
  14. def push(self, x):
  15. self.stack1.append(x)
  16. # 出栈
  17. def pop(self,):
  18. if self.stack2:
  19. return self.stack2.pop()
  20. while self.stack1:
  21. self.stack2.append(self.stack1.pop())
  22. return self.stack2.pop()
  23. def isEmpty(self,):
  24. if len(self.stack1) == 0 and len(self.stack2) == 0:
  25. return True
  26. else:
  27. return False
  • Java实现: ```java import java.util.Stack;

public class StackToQueue{ private Stack stack1; private Stack stack2;

  1. public StackToQueue() {
  2. }
  3. public StackToQueue(Stack<T> stack1, Stack<T> stack2) {
  4. this.stack1 = stack1;
  5. this.stack2 = stack2;
  6. }
  7. // 入队
  8. public void enqueue(T x){
  9. this.stack1.push(x);
  10. }
  11. // 出队
  12. public T dequeue(){
  13. if (!this.stack2.isEmpty()){
  14. return this.stack2.pop();
  15. } else{
  16. while (!this.stack1.isEmpty()){
  17. this.stack2.add(this.stack1.pop());
  18. }
  19. return this.stack2.pop();
  20. }
  21. }
  22. // 返回队首
  23. public T top(){
  24. if (!this.stack2.isEmpty()){
  25. return this.stack2.pop();
  26. } else{
  27. while (!this.stack1.isEmpty()){
  28. this.stack2.add(this.stack1.pop());
  29. }
  30. return this.stack2.peek();
  31. }
  32. }
  33. // 判空
  34. public boolean isEmpty(){
  35. if (this.stack1.isEmpty() && this.stack2.isEmpty()){
  36. return true;
  37. }else{
  38. return false;
  39. }
  40. }
  41. @Override
  42. public String toString() {
  43. return "StackToQueue{" +
  44. "stack1=" + stack1 +
  45. ", stack2=" + stack2 +
  46. '}';
  47. }
  48. public static void main(String[] args) {
  49. Stack<Integer> stack1 = new Stack<>();
  50. Stack<Integer> stack2= new Stack<>();
  51. StackToQueue<Integer> queue = new StackToQueue<>(stack1, stack2);
  52. queue.enqueue(1);
  53. queue.enqueue(2);
  54. queue.enqueue(3);
  55. queue.enqueue(4);
  56. queue.enqueue(5);
  57. System.out.println(queue); //StackToQueue{stack1=[1, 2, 3, 4, 5], stack2=[]}
  58. System.out.println(queue.top()); // 1
  59. System.out.println(queue.dequeue()); // 1
  60. System.out.println(queue); // StackToQueue{stack1=[], stack2=[5, 4, 3, 2]}
  61. }

} ```