一、两个栈实现队列
思路:栈得特征就是先进后出,队列是先进先出。所以既然是两个栈实现队列。比如是一个数组[5,4,8,6,9,2]。我们希望输出是296854.所以可以先入第一个栈,这样的话5就在最下面,2在最上面。然后再判断第二个是否为空,如果是空的,再把第一个栈得数据依次取出来依次入第二个栈(一定要判断第二个栈是否为空,具体我现在还不明白,如果不为空,直接输出第二个栈)。这样的话,2就在最下面,5在最上面。然后再把第二个栈出栈,就可以和输入时候得顺序一致了,从而达到队列先进先出的效果。
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
}
public int pop() {
if(stack2.empty())
{
while(!(stack1.empty()))
{
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
}
把这个算法测试一下
import java.util.Scanner;
import java.util.Stack;
public class StackQueue {
Stack<Integer> stack1=new Stack<Integer>();
Stack<Integer> stack2=new Stack<Integer>();
public void Push(int node)
{
stack1.push(node);
}
public void Pop()
{
if(stack2.empty())
{
while(!(stack1.empty()))
{
stack2.push(stack1.pop());
}
}
while(!(stack2.empty()))
{
System.out.print(stack2.pop()+" ");
}
}
public static void main(String[] args)
{
StackQueue sa=new StackQueue();
Scanner s=new Scanner(System.in);
int n=s.nextInt();
int[]arr=new int[n];
for(int i=0;i<n;i++)
{
arr[i]=s.nextInt();
}
for(int i=0;i<n;i++)
{
sa.Push(arr[i]);
}
System.out.println(sa.stack1);
sa.Pop();
}
}
输入:
6
8 4 5 2 3 0
输出:
[8,4,5,2,3,0]
8 4 5 2 3 0
注意:在输入里面(1)第一次输入n和第二次输入数据是默认回车换行的
(2)输入数组得时候,要用空格隔开
(3)如果直接输出栈得话。从底到上(正好和平时取出的顺序相反),且是在一个大括号里。
二、两个队列实现栈(1 2 3 4 5 6)
思路:同样,在进栈环节也是将数据进入第一个队列。因为队列是先进先出,所以即便把第一个队列值取出(12345顺序取出)放在第二个队列(还是12345)也还是输入的顺序,但是我们要得到(54321).所以两个队列实现栈比两个栈实现队列难一些。
具体想法是把第一个队列除了最后一个元素外都进第二个队列,然后再输出第一个队列的最后一个元素。然后这时第一个队列空了,第二个队列n-1个数。再把这n-1个数进队列一,这时候第一个队列n-1个元素,第二个队列又空了,然后再把第一个队列除了最后一个之外进第二个队列,然后再输出第一个队列得最后一个元素。然后此时第二个队列是n-2个,第一个队列空了。然后再进行之前得操作,直到第一个队列没有元素为止。
直接实现测试代码:
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
public class QueueStack {
Queue<Integer> q1=new LinkedList<Integer>();
Queue<Integer> q2=new LinkedList<Integer>();
public void Add(int node)
{
q1.add(node);
}
public void Pull()
{
if(q2.isEmpty())
{
while(!(q1.isEmpty()))
{
int len=q1.size();
for(int i=0;i<len-1;i++)
{
q2.add(q1.remove());
}
System.out.print(q1.remove()+" ");
if(q1.isEmpty())
{
while(!(q2.isEmpty()))
{
q1.add(q2.remove());
}
}
}
}
}
public static void main(String[] args)
{
QueueStack Q=new QueueStack();
int n;
Scanner s=new Scanner(System.in);
n=s.nextInt();
int[] arr=new int[n];
for(int i=0;i<n;i++)
{
arr[i]=s.nextInt();
}
for(int i=0;i<n;i++)
{
Q.Add(arr[i]);
}
Q.Pull();
}
注意:
(1)定义队列不像定义栈那么简单,需要利用多态性通过实现类来定义
(2)队列的进队是add()函数,出队是remove()和pull(),对应栈中的pop()。也是取出当前元素,删除这个节点的意思。peek()和element()对应于栈中的peek,只读取头元素,不删除。
(3)判断是否为空,栈中是empty(),队列中是isEmpty()。
(4)队列原样输出也是和栈一样的,从头到尾(就是和输入顺序一样)