栈和队列
一、栈
栈:先进后出(LIFO),就像往瓶子里放东西一样,先放进去的东西要最后才取的出来。
实现:
- 数组实现
- 动态数组实现
- 链表实现
运用:
- 用栈判断算式中的符号是否匹配
- 把中缀表达式改为后缀表达式
- 已知字符串的中间值,判断字符串是否为回文
二、队列
队列:先进先出(FIFO),就像是在排队一样,先排队的人买到东西后会先出来,要加入队列需要往后面加入
实现:
- 简单的循环数组实现
- 动态的循环数组实现
- 链表实现
三、有关栈和队列的一些问题解决
示例一:
用2个栈实现队列:
class MyQueue {
private Stack<Integer> a;// 输入栈
private Stack<Integer> b;// 输出栈
public MyQueue() {
a = new Stack<>();
b = new Stack<>();
}
public void push(int x) {
a.push(x);
}
public int pop() {
// 如果b栈为空,则将a栈全部弹出并压入b栈中,然后b.pop()
if(b.isEmpty()){
while(!a.isEmpty()){
b.push(a.pop());
}
}
return b.pop();
}
public int peek() {
if(b.isEmpty()){
while(!a.isEmpty()){
b.push(a.pop());
}
}
return b.peek();
}
public boolean empty() {
return a.isEmpty() && b.isEmpty();
}
}
示例二:
用2个队列实现栈:
class MyStack {
//队列
Queue queue;
//直接保存栈顶元素
int top;
/** Initialize your data structure here. */
public MyStack() {
//LinkedList实现了Queue接口,所以可以把LinkedList当作一个队列来使用
queue = new LinkedList();
}
/** Push element x onto stack. */
public void push(int x) {
//更新栈顶元素
top = x;
//将栈顶元素加入到队列尾
queue.offer(top);
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
//使用一个临时队列来更新
Queue temp = new LinkedList();
//因为要返回弹出的元素,所以事先保存下来
int oldTop = top;
int size = queue.size();
//循环更新每个元素,执行到最后时栈顶元素也更新了
for(int i = 0; i < size -1 ; i++){
top = (int) queue.remove();
temp.offer(top);
}
//更新队列(栈)
queue = temp;
return oldTop;
}
/** Get the top element. */
public int top() {
return top;
}
/** Returns whether the stack is empty. */
public boolean empty() {
return queue.size() == 0 ? true : false;
}
}
示例三:
逆转队列,只用入列和出列的操作:
Stack stack = new Stack();
while(!IsemptyQueue()){
stack.push(Q.deQueue());
}
while(stack != null){
Q.enQueue(stack.pop());
}