232.用栈实现队列、
代码:
class MyQueue {
Stack<Integer> stackIn;
Stack<Integer> stackOut;
public MyQueue() {
stackIn = new Stack<>(); // 输入栈
stackOut = new Stack<>(); // 输出栈
}
// 将一个元素放入队列的尾部
// 入队列直接放到输入栈里就可以
public void push(int x) {
stackIn.push(x);
}
// 从从队列首部移除元素 并返回该元素
// 出队 需要输出栈
public int pop() {
// 调用自己实现的接口函数:把stackin的所有元素放到stackout
dumpstackIn();
return stackOut.pop();
}
// 返回队列首部的元素
public int peek() {
dumpstackIn();
// 利于栈的 peek()
return stackOut.peek();
}
// 返回队列是否为空
public boolean empty() {
return stackIn.isEmpty() && stackOut.isEmpty();
}
// 如果stackout为空,将stackin的元素 全部 放到stackout里
private void dumpstackIn(){
// 如果stackout不为空,直接return
if (!stackOut.isEmpty()) return;
// 到这里默认stackout为空
while (!stackIn.isEmpty()){
stackOut.push(stackIn.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();
*/
- 实现dumpstackIn()函数接口:如果stackout为空,将stackin的元素 全部 放到stackout里
- 需要用两个栈,实现队列
225. 用队列实现栈
代码:
class MyStack {
Queue<Integer> queue1; // 和栈中保持一样元素的队列
Queue<Integer> queue2; // 辅助队列
public MyStack() {
queue1 = new LinkedList<>();
queue2 = new LinkedList<>();
}
// 元素 x 入栈
public void push(int x) {
// 放到辅助队列2
queue2.offer(x);
// 如果队列1不为空,就把队列1的元素复制到队列2
while (!queue1.isEmpty()){
queue2.offer(queue1.poll());
}
// 临时队列
// 最后交换queue1和queue2,将元素都放到queue1中
Queue<Integer> queueTemp;
queueTemp = queue1;
queue1 = queue2;
queue2 = queueTemp;
}
// 移除栈顶元素
public int pop() {
// 因为queue1中的元素和栈中的保持一致,所以这个和下面两个的操作只看queue1即可
return queue1.poll();
}
// 获取栈顶元素
public int top() {
return queue1.peek();
}
// 返回栈是否为空
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();
*/
要用两个队列来模拟栈,只不过没有输入和输出的关系,而是另一个队列完全用来备份的!
如下面动画所示,用两个队列que1和que2实现队列的功能,que2其实完全就是一个备份的作用
- 把que1最后面的元素以外的元素都备份到que2
- 弹出最后面的元素
- 把其他元素从que2导回que1
queue和deque的区别
http://t.csdn.cn/cOn1r
queue
- 单端队列
- queue从队首弹出,先入先出
- queue只能从队首删除元素, 但是两端都能访问。
void add(Object e):将指定元素加入此队列的尾部;
Object element():获取队列头部的元素,但是不删除该元素;
boolean offer(Object e):将指定的元素插入此队列的尾部;
Object peek():返回队列头部的元素,但是不删除该元素。如果队列为空,则返回null;
Object poll():返回队列头部的元素,并删除该元素。如果队列为空,则返回null;
Object remove():获取队列头部的元素,并删除该元素。
LinkedList 提供了上述方法以支持队列的行为,并且它实现了 Queue 接口,因此 LinkedList 可以作为 Queue 的一种实现。LinkedList 也可以向上转型为 Queue,如
Queue<Integer> queue = new LinkedList<Integer>();
deque
- 双端队列
- 可以在队头队尾进行入队出队操作
Deque 是 Queue 的子接口,用来表示双端队列。Deque 的实现类有 LinkedList 和 ArrayDeque,能够实现队列和栈的功能。
ArrayDeque 类
ArrayDeque 类是 Deque 接口的大小可变数组的实现。为了满足可以同时在数组两端插入或删除元素的需求,该数组以循环数组的方式实现。
Queue 方法 | 等效 Deque 方法 |
---|---|
add(e) | addLast(e) |
offer(e) | offerLast(e) |
remove() | removeFirst() |
poll() | pollFirst() |
element() | getFirst() |
peek() | peekFirst() |
Deque<Integer> queue = new LinkedList<>();
// Deque<Integer> queue= new ArrayDeque<>();
queue.addLast(5);// queue[5]
queue.addLast(2);// queue[5, 2]
queue.addLast(4);// queue[5, 2, 4]
queue.addLast(3);// queue[5, 2, 4, 3]
System.out.println(queue.pollFirst());// queue[2, 4, 3]
System.out.println(queue.pollFirst());// queue[4, 3]
-
queue可以访问两端但是只能修改队头,而deque可以访问两端并且可以在队首和队尾删除和插入元素
-
由于deque两端都可以压入,只用个push的话到底是用哪端压入呢?所以有了push_back()和push_front()
-
同样,pop()是弹出,所以有pop_back()和pop_front();
-
而取数的话,queue和deque都可以从两端取,所以都是front()和back()。