一、栈与队列
队列是先进先出,栈是先进后出。
- Java中stack 是容器么?
stack是继承自Vector,底层使用数组存储、用来模拟栈的一个java集合。同时也是线程安全的。使用场景比如说倒序输出、XML语法检查。 - 我们使用的Java容器中stack是如何实现的?
来源博客JDK中的栈实现 - stack 提供迭代器来遍历stack空间么?
栈提供push 和 pop 等等接口,所有元素必须符合先进后出规则,所以栈不提供走访功能,也不提供迭代器(iterator)。不像是set 或者map 提供迭代器iterator来遍历所有元素
java中栈与队列的介绍:博客来源
二、用栈实现队列(LeetCode232)
根据栈和队列进出原则,定义两个出入栈来实现,由于pop和peek用到了相同的功能,因此定义一个函数去实现被用来调用
class MyQueue {
Stack<Integer> in = new Stack<>();
Stack<Integer> out =new Stack<>();
public MyQueue() {
}
public void push(int x) {
in.push(x);
}
public int pop() {
stack();
return out.pop();
}
public int peek() {
stack();
return out.peek();
}
public boolean empty() {
return in.isEmpty() && out.isEmpty();
}
// 如果out为空,那么将in中的元素全部放到out中
public void stack(){
if(!out.isEmpty()) return;
while(!in.isEmpty()){
out.push(in.pop());
}
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/
和上面实现方法类似定义两个栈,定义一个cope函数实现反转来实现
class MyQueue {
// 从队尾入 从队头出
/** Initialize your data structure here. */
// 一个主栈 一个缓存
Stack<Integer> stk = new Stack<>();
Stack<Integer> cache = new Stack<>();
public MyQueue() {
}
// 两个栈实现队列 push 插入队尾 pop 队首元素弹出返回改元素 peek 返回对手 empty 是否为空
/** Push element x to the back of queue. */
public void push(int x) {
stk.push(x);
}
public void copy(Stack<Integer> a, Stack<Integer> b){
while(a.size()!=0){
b.push(a.peek());
a.pop();
}
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
copy(stk,cache); //反转一次
int res = cache.peek(); //此时栈顶就是队头就是栈底
cache.pop(); //弹出
copy(cache, stk); //反转回来
return res;
}
/** Get the front element. */
public int peek() {
copy(stk, cache);
int res = cache.peek(); //得到队头
copy(cache, stk);
return res;
}
/** Returns whether the queue is empty. */
public boolean empty() {
return stk.isEmpty();
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/
三、用队列实现栈(LeetCode)
用两个队列来实现或者一个队列也行(Java里的栈与队列忘光了。。。)
class MyStack {
Queue<Integer> queue1; // 和栈中保持一样元素的队列
Queue<Integer> queue2; // 辅助队列
/** Initialize your data structure here. */
public MyStack() {
queue1 = new LinkedList<>();
queue2 = new LinkedList<>();
}
/** Push element x onto stack. */
public void push(int x) {
queue2.offer(x); // 先放在辅助队列中
while (!queue1.isEmpty()){
queue2.offer(queue1.poll());
}
Queue<Integer> queueTemp;
queueTemp = queue1;
queue1 = queue2;
queue2 = queueTemp; // 最后交换queue1和queue2,将元素都放到queue1中
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
return queue1.poll(); // 因为queue1中的元素和栈中的保持一致,所以这个和下面两个的操作只看queue1即可
}
/** Get the top element. */
public int top() {
return queue1.peek();
}
/** Returns whether the stack is empty. */
public boolean empty() {
return queue1.isEmpty();
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/
class MyStack {
Queue<Integer> queue;
public MyStack() {
queue = new LinkedList<>();
}
//每 offer 一个数(A)进来,都重新排列,把这个数(A)放到队列的队首
public void push(int x) {
queue.offer(x);
int size = queue.size();
//移动除了 A 的其它数
while(size-- > 1){
queue.offer(queue.poll());
}
}
public int pop() {
return queue.poll();
}
public int top() {
return queue.peek();
}
public boolean empty() {
return queue.isEmpty();
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/