1. 栈实现队列:即我们要在底层通过栈来实现队列的操作。
//将栈转换成队列 通过队列的方法来实现一些操作 底层是通过栈来存储的
public class StackToQueue {
public static void main(String[] args) {
StackImplByQueue<Integer> stackImplByQueue = new StackImplByQueue<>();
for(int i = 1; i <= 5; i++){
stackImplByQueue.offer(i);
}
System.out.println(stackImplByQueue);
System.out.println(stackImplByQueue.poll());
}
}
class StackImplByQueue<E> implements Queue<E>{
ArrayStack<E> stackA; //stackA为存放数据的主栈
ArrayStack<E> stackB; //stackB为临时栈
public StackImplByQueue(){
stackA = new ArrayStack<>();
stackB = new ArrayStack<>();
}
//向队列中添加元素,通过栈来实现
@Override
public void offer(E element) {
stackA.push(element);
}
//删除队首元素,通过栈来实现
/*
先将stackA主栈中的元素循环弹出 并添加到stackB临时栈中 直至stackA中只剩一个元素
将stackA主栈中的最后一个元素弹出
最后将stackB临时栈中的元素循环放回stackA主栈中 直至临时栈为空
*/
@Override
public E poll() {
if(stackA.isEmpty()){
throw new IllegalArgumentException("stackA is not null");
}
while (stackA.size() != 1){
stackB.push(stackA.pop());
}
E ele = stackA.pop();
while (!stackB.isEmpty()){
stackA.push(stackB.pop());
}
return ele;
}
//查看队首元素,通过栈来实现
/*
先将stackA主栈中的元素循环弹出 并添加到stackB临时栈中 直至stackA中只剩一个元素
查看stackA主栈中的最后一个元素
最后将stackB临时栈中的元素循环放回stackA主栈中 直至临时栈为空
*/
@Override
public E element() {
if(isEmpty()) {
throw new IllegalArgumentException("stackA is not null");
}
while (stackA.size() != 1){
stackB.push(stackA.pop());
}
E ele = stackA.peek();
while (!stackB.isEmpty()){
stackA.push(stackB.pop());
}
return ele;
}
//判断队列是否为空 即判断stackA主栈是否为空
@Override
public boolean isEmpty() {
return stackA.isEmpty();
}
//清空队列中的全部元素 即清空stackA主栈即可
@Override
public void clear() {
stackA.clear();
}
//获取队列中有效元素的个数 即获取stackA主栈有效元素的个数
@Override
public int size() {
return stackA.size();
}
//迭代队列 即队列stackA主栈即可
@Override
public Iterator iterator() {
return stackA.iterator();
}
//格式化输出队列 即输出stackA主栈即可
@Override
public String toString() {
return stackA.toString();
}
}
2. 队列实现栈:即我们要在底层通过队列来实现栈的操作。
//将队列转换成栈 通过栈的方法来实现一些操作 底层是通过队列来存储的
public class QueueToStack {
public static void main(String[] args) {
QueueImplByStack<Integer> stack = new QueueImplByStack<>();
for(int i = 0; i < 5; i++){
stack.push(i);
}
System.out.println(stack);
System.out.println(stack.pop());
System.out.println(stack.peek());
}
}
class QueueImplByStack<E> implements Stack<E> {
private ArrayQueue<E> queueA; //存放数据的容器
private ArrayQueue<E> queueB; //存放数据的容器
public QueueImplByStack() {
queueA = new ArrayQueue<>();
queueB = new ArrayQueue<>();
}
//获取栈中有效元素的个数 即那个队列不为空 获取的就是那个队列的有效元素个数
@Override
public int size() {
if(queueA.isEmpty() && queueB.isEmpty()){
return 0;
}else if(!queueA.isEmpty()){
return queueA.size();
}else{
return queueB.size();
}
}
//判断栈是否为空 当两个队列同时为空时 则表示栈为空
@Override
public boolean isEmpty() {
return queueA.isEmpty() && queueB.isEmpty();
}
//先栈中添加元素
/*
当两个队列都为空时 就默认向队列A添加元素
当队列A不为空时 就直接向队列A添加元素即可
当队列B不为空时 就直接向队列B添加元素即可
*/
@Override
public void push(E element) {
if(queueA.isEmpty() && queueB.isEmpty()){
queueA.offer(element);
}else if(!queueA.isEmpty()){
queueA.offer(element);
}else if(!queueB.isEmpty()){
queueB.offer(element);
}
}
//弹出栈顶元素
/*
当队列A不为空时 就要依次出队元素并添加到队列B中 直至队列A中只剩一个元素(即为栈的栈顶元素) 出队最后一个元素即可
当队列B不为空时 就要依次出队元素并添加到队列A中 直至队列B中只剩一个元素(即为栈的栈顶元素) 出队最后一个元素即可
这里不需要再将队列B中的元素重新放回队列A 下次添加元素直接添加到队列B即可 出站元素直接操作队列B即可
*/
@Override
public E pop() {
E ele;
if(queueA.isEmpty() && queueB.isEmpty()){
throw new IllegalArgumentException("queue is not null");
}else if(!queueA.isEmpty()){
while (queueA.size() != 1) {
queueB.offer(queueA.poll());
}
ele = queueA.poll();
}else {
while (queueB.size() != 1) {
queueA.offer(queueB.poll());
}
ele = queueB.poll();
}
return ele;
}
//查看栈顶元素
/*
当队列A不为空时 就要依次出队元素并添加到队列B中 直至队列A中只剩一个元素(即为栈的栈顶元素)
出队最后一个元素并返回 但是还要将队后一个元素再入队到队列B中 因为要保持始终只有一个队列中存放元素
当队列B不为空时 就要依次出队元素并添加到队列A中 直至队列B中只剩一个元素(即为栈的栈顶元素)
出队最后一个元素并返回 但是还要将队后一个元素再入队到队列A中 因为要保持始终只有一个队列中存放元素
*/
@Override
public E peek() {
E ele;
if(queueA.isEmpty() && queueB.isEmpty()){
throw new IllegalArgumentException("queue is not null");
}else if(!queueA.isEmpty()){
while (queueA.size() != 1){
queueB.offer(queueA.poll());
}
ele = queueA.poll();
queueB.offer(ele);
}else{
while (queueB.size() != 1){
queueA.offer(queueB.poll());
}
ele = queueB.poll();
queueA.offer(ele);
}
return ele;
}
//清空栈中所有元素 即清空那个不为空的队列即可
@Override
public void clear() {
if(!queueA.isEmpty()){
queueA.clear();
}else{
queueB.clear();
}
}
//迭代栈 即返回那个不为空的队列的迭代器即可
@Override
public Iterator iterator() {
if(!queueA.isEmpty()){
return queueA.iterator();
}else{
return queueB.iterator();
}
}
//格式化输出队列 即输出那个不为空的队列即可
@Override
public String toString() {
if(isEmpty()){
return "[]";
}else if(!queueA.isEmpty()){
return queueA.toString();
}else{
return queueB.toString();
}
}
}