如何使用数组实现栈和队列?
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
来表示当前数组中的元素个数外,还需要first
和last
来表示队头元素和队尾元素的位置,将数组循环使用。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 } } }
如何构建获取最小元素的栈
-
思路1:
array
和mins
分别存储入栈的元素和当前已入栈元素中最小的元素- 入栈:如果此时栈为空,则将元素同时压入两个数组中;如果此时栈不为空且入栈的元素小于
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: 同样使用
array
和mins
来存储入栈的元素和当前栈中最小的元素,不同之处在于入栈和出栈更为简单,假设当前栈不为空:- 入栈:如果入栈元素
x
大于等于mins
的栈顶元素,则将x
压入array
中,而mins
重新压入它当前的栈顶元素 - 出栈:
array
和mins
同时出栈
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]} } }