一、栈与队列
- 栈(stack):先进后出(First In Last Out),栈分为栈顶(top)与栈底(bottom),即是每次入栈(push),都是从一个口进,出栈(pop)也是从同一个口出。java提供了对此结构的实现java.util.Stack。
- 队列(queue):先进先出(First In First Out),队列分为队首(front)和队尾(rear),即每次入队列,都是从一个方向入,出队列,从也是从这个方向出(就好像我们排队做核酸)。java提供了对此结构的实现java.util.LinkedList。
二、用栈实现队列
实现思想:用栈实现队列的特性(FIFO),用一个栈肯定实现不了,因为栈的特性是FILO,与队列相反,所以至少用两个栈来实现。那要保证队列的先进先出,就需要在入栈与出栈的顺序上做文章了,代码实现如下。
/**
* 此处只使用两个栈模拟队列的FIFO
*/
private static void stackQueue() {
// jdk提供的队列
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < 7; i++) {
queue.add(i);
}
System.out.println("实际队列中元素: 队首 " + queue + " 队尾");
// 实际队列出队列结果
System.out.print("实际队列出队列结果:");
for (int i = 0; i < 7; i++) {
System.out.print(queue.poll() + " ");
}
// 模拟队列出队列结果
System.out.println();
System.out.print("模拟队列出队列结果:");
// 声明两个栈
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
// 交替入栈,奇数入stack1,偶数入stack2
// 这个入栈规则可自定义
for (int i = 0; i < 7; i++) {
if (i % 2 != 0) {
stack1.push(i);
} else {
stack2.push(i);
}
}
// 模拟出队列
// 核心思想,从第一个被使用的栈,开始出栈
// 第一步,把stack2的栈底元素,取出,其余元素入栈stack1
// 第二步,把stack1的栈底元素,取出,其余元素入栈stack2
// 第三步,重复步骤一、二,直至stack2与stack1都为空
for (int i = 0; i < 7; i++) {
if (i % 2 != 0) {
while (!stack1.isEmpty()) {
if (stack1.size() != 1) {
stack2.push(stack1.pop());
} else {
System.out.print(stack1.pop() + " ");
}
}
} else {
while (!stack2.isEmpty()) {
if (stack2.size() != 1) {
stack1.push(stack2.pop());
} else {
System.out.print(stack2.pop() + " ");
}
}
}
}
}
测试结果:
三、用队列实现栈
实现思路:与栈实现队列思想相同,在队列的数量和入队列出队列上做文章,代码如下。
/**
* 此处只使用两个队列模拟栈的FILO
*/
private static void queueStack() {
// jdk提供的栈
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < 7; i++) {
stack.push(i);
}
System.out.println("实际栈中元素: 栈底 " + stack + " 栈顶");
// 实际栈出栈结果
System.out.print("实际栈出栈结果:");
for (int i = 0; i < 7; i++) {
System.out.print(stack.pop() + " ");
}
System.out.println();
// 声明两个队列
Queue<Integer> queue1 = new LinkedList<>();
Queue<Integer> queue2 = new LinkedList<>();
// 所有数据入队列1,入哪个队列随意
for (int i = 0; i < 7; i++) {
queue1.add(i);
}
// 模拟出栈
// 核心思想:
// 第一步:从queue1取出对尾数据,其余数据入queue2
// 第二步:从queue2取出堆尾数据,其余数据入queue1
// 第三步:重复步骤一、二,直至两个队列为空
System.out.print("使用队列模拟栈出栈结果:");
for (int i = 0; i < 7; i++) {
while (!queue1.isEmpty()) {
if (queue1.size() != 1) {
queue2.add(queue1.poll());
} else {
System.out.print(queue1.poll() + " ");
}
}
while (!queue2.isEmpty()) {
if (queue2.size() != 1) {
queue1.add(queue2.poll());
} else {
System.out.print(queue2.poll() + " ");
}
}
}
}
测试结果: