大佬们好!我是LKJ_Coding,一枚初级马牛,正在努力在代码的丛林中找寻自己的方向。如果你也曾在调试中迷失,或是在文档中翻滚,那我们一定有许多共同话题可以聊!今天,我带着满满的代码“干货”来和大家分享,学不学无所谓,反正我先吐槽了!
前言
栈(Stack)和队列(Queue)是常见的线性数据结构,它们广泛应用于算法和数据处理过程中。在 Java 中,栈和队列都可以通过现有的类(如 Stack
和 Queue
)直接使用,也可以通过自定义类实现,通常基于数组或链表来实现。
本文将介绍栈和队列的基本概念,如何使用 Java 自带的 Stack
和 Queue
类来实现栈和队列操作,如何使用数组或链表自定义栈和队列,并通过代码示例演示栈和队列的实现。
1. 栈和队列的基本概念
1.1 栈(Stack)
栈是一种后进先出(LIFO,Last In First Out)的数据结构,即最后被压入栈的数据最先被弹出。栈的操作有:
- push:将元素压入栈顶。
- pop:从栈顶移除并返回元素。
- peek:查看栈顶元素,但不移除它。
- isEmpty:检查栈是否为空。
栈常用于以下场景:
- 函数调用的递归栈。
- 表达式的计算(如括号匹配)。
- 浏览器的历史记录等。
1.2 队列(Queue)
队列是一种先进先出(FIFO,First In First Out)的数据结构,即最先被入队的数据最先被出队。队列的操作有:
- enqueue(或
offer
):将元素添加到队列的尾部。 - dequeue(或
poll
):从队列头部移除并返回元素。 - peek:查看队列头部的元素,但不移除它。
- isEmpty:检查队列是否为空。
队列常用于以下场景:
- 任务调度。
- 数据流处理。
- 广度优先搜索(BFS)。
2. 使用 Stack
和 Queue
类
Java 提供了内置的 Stack
类和 Queue
接口,以及实现类 LinkedList
和 ArrayDeque
来实现栈和队列。
2.1 使用 Stack
类实现栈
Java 的 Stack
类提供了栈的基本操作,如 push()
、pop()
和 peek()
。
2.1.1 示例:使用 Stack
类实现栈操作
import java.util.Stack;
public class StackExample {
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
// 压入元素
stack.push(10);
stack.push(20);
stack.push(30);
// 查看栈顶元素
System.out.println("Peek: " + stack.peek()); // 输出 30
// 弹出元素
System.out.println("Pop: " + stack.pop()); // 输出 30
// 查看栈顶元素
System.out.println("Peek after pop: " + stack.peek()); // 输出 20
// 检查栈是否为空
System.out.println("Is stack empty? " + stack.isEmpty()); // 输出 false
}
}
在这个示例中:
- 使用
push()
将元素压入栈。 - 使用
peek()
查看栈顶元素,但不移除它。 - 使用
pop()
从栈顶移除并返回元素。
2.2 使用 Queue
接口实现队列
Queue
是一个接口,Java 提供了多个实现类,如 LinkedList
和 ArrayDeque
,这两者都可以用来实现队列。
2.2.1 示例:使用 LinkedList
实现队列
import java.util.LinkedList;
import java.util.Queue;
public class QueueExample {
public static void main(String[] args) {
Queue<Integer> queue = new LinkedList<>();
// 入队操作
queue.offer(10);
queue.offer(20);
queue.offer(30);
// 查看队头元素
System.out.println("Peek: " + queue.peek()); // 输出 10
// 出队操作
System.out.println("Poll: " + queue.poll()); // 输出 10
// 查看队头元素
System.out.println("Peek after poll: " + queue.peek()); // 输出 20
// 检查队列是否为空
System.out.println("Is queue empty? " + queue.isEmpty()); // 输出 false
}
}
在这个示例中:
- 使用
offer()
将元素入队。 - 使用
peek()
查看队头元素,但不移除它。 - 使用
poll()
从队头移除并返回元素。
2.3 使用 ArrayDeque
实现队列
ArrayDeque
是 Deque
接口的一个实现,它提供了比 LinkedList
更快的队列操作。ArrayDeque
可用作队列或双端队列(Deque
)。
2.3.1 示例:使用 ArrayDeque
实现队列
import java.util.ArrayDeque;
import java.util.Queue;
public class ArrayDequeExample {
public static void main(String[] args) {
Queue<Integer> queue = new ArrayDeque<>();
// 入队操作
queue.offer(10);
queue.offer(20);
queue.offer(30);
// 查看队头元素
System.out.println("Peek: " + queue.peek()); // 输出 10
// 出队操作
System.out.println("Poll: " + queue.poll()); // 输出 10
// 查看队头元素
System.out.println("Peek after poll: " + queue.peek()); // 输出 20
// 检查队列是否为空
System.out.println("Is queue empty? " + queue.isEmpty()); // 输出 false
}
}
2.4 自定义栈和队列
除了使用 Java 内置的 Stack
和 Queue
类,你也可以使用数组或链表自定义实现栈和队列。
2.4.1 示例:自定义栈
public class CustomStack {
private int[] stack;
private int top;
public CustomStack(int size) {
stack = new int[size];
top = -1; // 栈为空
}
public void push(int value) {
if (top < stack.length - 1) {
stack[++top] = value;
} else {
System.out.println("Stack Overflow");
}
}
public int pop() {
if (top >= 0) {
return stack[top--];
} else {
System.out.println("Stack Underflow");
return -1;
}
}
public int peek() {
if (top >= 0) {
return stack[top];
} else {
System.out.println("Stack is empty");
return -1;
}
}
public boolean isEmpty() {
return top == -1;
}
}
2.4.2 示例:自定义队列
public class CustomQueue {
private int[] queue;
private int front, rear, size;
public CustomQueue(int size) {
queue = new int[size];
front = rear = -1;
this.size = size;
}
public void enqueue(int value) {
if (rear < size - 1) {
if (front == -1) front = 0;
queue[++rear] = value;
} else {
System.out.println("Queue is full");
}
}
public int dequeue() {
if (front <= rear && front != -1) {
return queue[front++];
} else {
System.out.println("Queue is empty");
return -1;
}
}
public int peek() {
if (front <= rear && front != -1) {
return queue[front];
} else {
System.out.println("Queue is empty");
return -1;
}
}
public boolean isEmpty() {
return front == -1 || front > rear;
}
}
3. 总结
- 栈(Stack)是后进先出(LIFO)的数据结构,Java 提供了
Stack
类来实现栈操作。 - 队列(Queue)是先进先出(FIFO)的数据结构,Java 提供了
Queue
接口及其实现类LinkedList
和ArrayDeque
来实现队列操作。 - Java 中的栈和队列操作既可以使用内置的类,也可以通过数组或链表实现自定义的栈和队列。
通过这些数据结构,我们可以在 Java 中高效地处理需要栈和队列特性的任务,如递归、任务调度、事件处理等。
好啦,废话不多说,今天的分享就到这里!如果你觉得我这“初级马牛”还挺有趣,那就请给我点个赞、留个言、再三连击三连哦!让我们一起“成精”吧!下次见,不见不散!