数组、栈和队列之间的相互转换(Python + Java实现)

14 篇文章 0 订阅
9 篇文章 1 订阅

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

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

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

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

数组实现栈:
  • python实现

    class Stack:
        def __init__(self, array = None):
            super().__init__()
            self.array = array
    
        # 入栈
        def push(self, x):
            self.array.append(x)
    
        # 出栈
        def pop(self,):
            if len(self.array) == 0:
                return
    
            return self.array.pop()
    
        # 取栈顶元素
        def top(self,):
            if len(self.array) == 0:
                return
    
            return self.array[-1]
    
        # 判空
        def isEmpty(self,):
            return True if self.array == [] else False
    
  • Java实现

    Java中的数组并没有python中list类似的方法,因此需要设置一个变量size来表示当前数组中的元素个数,以及方便进行栈顶元素的获取。

    public class ArrayToStack {
    
      public static class Array2Stack<T>{
          private T[] array;
          private int size;
    
          public Array2Stack() {
          }
    
          public Array2Stack(T[] array) {
              this.array = array;
              this.size = 0;
          }
    
    
          // 入栈
          public void push(T x){
              if (this.size == this.array.length){
                  throw new ArrayIndexOutOfBoundsException("the stack is full!");
              }
    
              this.array[size++] = x;
          }
          // 出栈
          public T pop(){
              if (isEmpty()){
                  throw new ArrayIndexOutOfBoundsException("the stack is empty");
              }
    
              return this.array[--size];
          }
          // 取栈顶元素
          public T top(){
              if (isEmpty()){
                  return null;
              }
              return this.array[size];
          }
    
          // 判空
          public boolean isEmpty(){
              boolean flag = this.size == 0 ? true : false;
              return flag;
          }
      }
    
      public static void main(String[] args) {
          int size = 10;
          Integer [] array = new Integer[size];
          Array2Stack<Integer> stack = new Array2Stack<>(array);
    
          // 入栈
          stack.push(1);
          stack.push(2);
          stack.push(3);
    
          // 出栈
          while(!stack.isEmpty()){
              System.out.println(stack.pop()); // 3, 2, 1
          }
    
          String[] arr = new String[size];
          Array2Stack<String> stack1 = new Array2Stack<>(arr);
          stack1.push("Forlogen");
          stack1.push("kobe");
    
          while(!stack1.isEmpty()){
              System.out.println(stack1.pop()); // kobe, Forlogen
          }
      }
    }
    
    
数组实现队列
  • python实现

    class Queue:
        def __init__(self, array = None):
            super().__init__()
            self.array = array
    
        # 入队
        def enqueue(self, x):
            self.array.append(x)
    
        # 出队
        def dequeue(self):
            if len(self.array) == 0:
                return
    
            return self.array.pop(0)
    
        # 判空
        def isEmpty(self,):
            return True if self.array == [] else False
    
    
  • Java实现

    使用数组实现队列除了需要变量size来表示当前数组中的元素个数外,还需要firstlast来表示队头元素和队尾元素的位置,将数组循环使用。

    
    import java.util.Arrays;
    
    public class ArrayToQueue<T>{
        private T[] array;
        private int size = 0;
        private int first = 0;
        private int last = 0;
    
        public ArrayToQueue() {
        }
    
        public ArrayToQueue(T[] array) {
            if (size < 0){
                throw new IllegalArgumentException("the size is less than 0!");
            }
            this.array = array;
        }
    
        // 入队
        public void enqueue(T x){
            if (this.size == this.array.length){
                throw new ArrayIndexOutOfBoundsException("the queue is full!");
            }
            size++;
            this.array[this.last] = x;
            last = last == this.array.length - 1 ? 0 : last + 1;
        }
    
        // 出队
        public T dequeue(){
            if (isEmpty()){
                throw new ArrayIndexOutOfBoundsException("the queue is empty!");
            }
            size--;
            int tmp = first;
            first = first == this.array.length - 1 ? 0: first + 1;
            return this.array[tmp];
        }
    
        public boolean isEmpty(){
            boolean flag = this.size == 0 ? true : false;
            return flag;
        }
    
    
        public static void main(String[] args) {
            int size = 10;
            Integer[] array = new Integer[size];
            ArrayToQueue<Integer> queue = new ArrayToQueue<>(array);
    
            // 入队
            queue.enqueue(1);
            queue.enqueue(2);
            queue.enqueue(3);
    
            System.out.println(Arrays.toString(array));
            while(!queue.isEmpty()){
                System.out.println(queue.dequeue()); // 1, 2,3
            }
    
        }
    }
    
    

如何构建获取最小元素的栈

  • 思路1arraymins分别存储入栈的元素和当前已入栈元素中最小的元素

    • 入栈:如果此时栈为空,则将元素同时压入两个数组中;如果此时栈不为空且入栈的元素小于mins的末尾元素,则同时压入两个数组;如果此时栈不为空但入栈的元素大于mins的末尾元素,则只将入栈元素压入array
    • 出栈:同样需要判断当前array的栈顶元素和mins末尾元素的关系,从而来判断是否需要同时出栈,还是只对array执行出栈操作
    class MinStack:
        def __init__(self, array = None):
            super().__init__()
            self.array = array
            self.mins = []
    
        # 入栈
        def push(self, x):
            if len(self.mins) == 0:
                self.array.append(x)
                self.mins.append(x)
            else:
                if x < self.mins[-1]:
                    self.array.append(x)
                    self.mins.append(x)
                else:
                    self.array.append(x)
    
        # 出栈
        def pop(self,):
            if len(self.array) == 0:
                return
            elif self.top() == self.mins[-1]:
                self.mins.pop()
                return self.array.pop()
            else:
                return self.array.pop()
    
        # 获取栈中的最小元素
        def getMin(self, ):
            if len(self.array) == 0:
                return
            return self.mins[-1]
    
        # 取栈顶元素
        def top(self,):
            if len(self.array) == 0:
                return
    
            return self.array[-1]
    
  • 思路2: 同样使用arraymins来存储入栈的元素和当前栈中最小的元素,不同之处在于入栈和出栈更为简单,假设当前栈不为空:

    • 入栈:如果入栈元素x大于等于mins的栈顶元素,则将x压入array中,而mins重新压入它当前的栈顶元素
    • 出栈:arraymins同时出栈
    class MinStack:
        def __init__(self, array = None):
            super().__init__()
            self.array = array
            self.mins = []
    
        # 入栈
        def push(self, x):
            if len(self.mins) == 0:
                self.array.append(x)
                self.mins.append(x)
            else:
                if x < self.mins[-1]:
                    self.array.append(x)
                    self.mins.append(x)
                else:
                    self.mins.append(self.mins[-1])
                    self.array.append(x)
    
        # 出栈
        def pop(self,):
            if len(self.array) == 0:
                return
    
            self.mins.pop()
            return self.array.pop()
    
    
        # 获取栈中的最小元素
        def getMin(self, ):
            if len(self.array) == 0:
                return
            return self.mins[-1]
    
        # 取栈顶元素
        def top(self,):
            if len(self.array) == 0:
                return
    
            return self.array[-1]
    

如何使用队列实现栈?

  • python实现:

    Python的collections模块中的deque为一个双端队列,使用其中的append()入栈和使用pop()出栈,实现代码:

    from collections import deque
    
    class Stack:
        def __init__(self, array = None):
            super().__init__()
            self.queue = deque(array) 
    
        # 入栈  
        def push(self, x):
            self.queue.append(x)
    
        # 出栈
        def pop(self,):
            if (list(self.queue)) == 0:
                return
            return self.queue.pop()
    
        # 取栈顶元素
        def top(self,):
            if (list(self.queue)) == 0:
                return
    
            return list(self.queue)[-1]
    
        # 判空
        def isEmpty(self, ):
            return True if (list(self.queue)) == 0 else False
    
  • Java 实现:

    import java.util.LinkedList;
    import java.util.Queue;
    
    public class QueueToStack<T>{
        private Queue<T> queue1;
        private Queue<T> queue2;
    
        public QueueToStack(Queue<T> queue1, Queue<T> queue2) {
            this.queue1 = queue1;
            this.queue2 = queue2;
        }
    
        // 入栈
        public void push(T x){
            this.queue1.add(x);
        }
        // 出栈
        public T pop(){
            if (queue1.isEmpty()){
                throw new RuntimeException("stack is empty");
            }
            while (this.queue1.size() > 1){
                this.queue2.add(this.queue1.poll());
            }
            T res = this.queue1.poll();
            swap();
            return res;
        }
    
        // 交换引用
        private void swap() {
            Queue<T> tmp = this.queue2;
            queue2 = queue1;
            queue1 = tmp;
        }
        // 返回栈顶元素
        public T top(){
            if (queue1.isEmpty()){
                throw new RuntimeException("stack is empty");
            }
            while (this.queue1.size() > 1){
                this.queue2.add(this.queue1.poll());
            }
            T res = this.queue1.poll();
            this.queue2.add(res);
            swap();
            return res;
        }
    
        // 判空
        public boolean isEmpty(){
            if (this.queue1.isEmpty() && this.queue2.isEmpty()){
                return true;
            } else{
                return false;
            }
        }
    
    
        @Override
        public String toString() {
            return "QueueToStack{" +
                    "queue1=" + queue1 +
                    ", queue2=" + queue2 +
                    '}';
        }
    
        public static void main(String[] args) {
            Queue<Integer> queue1 = new LinkedList<>();
            Queue<Integer> queue2 = new LinkedList<>();
    
            QueueToStack<Integer> stack = new QueueToStack<>(queue1, queue2);
    
            stack.push(1);
            stack.push(2);
            stack.push(3);
            stack.push(4);
            stack.push(5);
            System.out.println(stack);  // QueueToStack{queue1=[1, 2, 3, 4, 5], queue2=[]}
    
            System.out.println(stack.top()); // 5
    
            stack.pop();
            System.out.println(stack); // QueueToStack{queue1=[1, 2, 3, 4], queue2=[]}
        }
    }
    

如何使用栈构建队列?

  • python实现:

    队列是一种先进先出的数据结构,而栈是一种后见先出的数据结构。因此需用一个栈stack1做入队,另一个stack2做出队。如果stack2不为空则直接弹出,否则需将stack1中的全部元素先压入stack2再从stack2中出栈。

    class Queue:
        def __init__(self):
            super().__init__()
            self.stack1 = []
            self.stack2 = []
    
        # 入栈
        def push(self, x):
            self.stack1.append(x)
    
        # 出栈
        def pop(self,):
            if self.stack2:
                return self.stack2.pop()
    
            while self.stack1:
                self.stack2.append(self.stack1.pop())
    
            return self.stack2.pop()
    
        def isEmpty(self,):
            if len(self.stack1) == 0 and len(self.stack2) == 0:
                return True
            else:
                return False
    
  • Java实现:

    import java.util.Stack;
    
    public class StackToQueue<T>{
        private Stack<T> stack1;
        private Stack<T> stack2;
    
        public StackToQueue() {
        }
    
        public StackToQueue(Stack<T> stack1, Stack<T> stack2) {
            this.stack1 = stack1;
            this.stack2 = stack2;
        }
    
        // 入队
        public void enqueue(T x){
            this.stack1.push(x);
        }
    
        // 出队
        public T dequeue(){
            if (!this.stack2.isEmpty()){
                return this.stack2.pop();
            } else{
                while (!this.stack1.isEmpty()){
                    this.stack2.add(this.stack1.pop());
                }
                return this.stack2.pop();
            }
        }
    
        // 返回队首
        public T top(){
            if (!this.stack2.isEmpty()){
                return this.stack2.pop();
            } else{
                while (!this.stack1.isEmpty()){
                    this.stack2.add(this.stack1.pop());
                }
                return this.stack2.peek();
            }
        }
    
        // 判空
        public boolean isEmpty(){
            if (this.stack1.isEmpty() && this.stack2.isEmpty()){
                return true;
            }else{
                return false;
            }
        }
    
        @Override
        public String toString() {
            return "StackToQueue{" +
                    "stack1=" + stack1 +
                    ", stack2=" + stack2 +
                    '}';
        }
    
    
        public static void main(String[] args) {
            Stack<Integer> stack1 = new Stack<>();
            Stack<Integer> stack2= new Stack<>();
    
            StackToQueue<Integer> queue = new StackToQueue<>(stack1, stack2);
    
            queue.enqueue(1);
            queue.enqueue(2);
            queue.enqueue(3);
            queue.enqueue(4);
            queue.enqueue(5);
            System.out.println(queue); //StackToQueue{stack1=[1, 2, 3, 4, 5], stack2=[]}
    
            System.out.println(queue.top()); // 1
    
            System.out.println(queue.dequeue()); // 1
            System.out.println(queue); // StackToQueue{stack1=[], stack2=[5, 4, 3, 2]}
    
        }
    }
    
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值