1. 队列的基本概念
队列是一种先进先出的线性数据结构。你可以把它想象成排队买票,最先排队的人最先买到票并离开队列。它主要有两个操作端:队首和队尾。元素从队尾添加,从队首移除。
2. 队列的基本操作
- 入队(enqueue):在队列的末尾添加一个元素。
- 出队(dequeue):从队列的开头移除一个元素。
- 查看队首(peek):查看队列的第一个元素。
- 检查队列是否为空(isEmpty):判断队列是否没有元素。
3. 队列的Java实现
在Java中,我们可以使用链表来实现队列。下面是一个简单的队列实现:
import java.util.LinkedList;
public class MyQueue {
private LinkedList<Integer> list;
public MyQueue() {
list = new LinkedList<>();
}
// 入队操作
public void enqueue(int data) {
list.addLast(data);
}
// 出队操作
public int dequeue() {
if (isEmpty()) {
System.out.println("Queue is empty, unable to dequeue.");
return -1; // 返回-1作为错误提示
}
return list.removeFirst();
}
// 查看队首元素
public int peek() {
if (isEmpty()) {
System.out.println("Queue is empty, no elements to peek.");
return -1; // 返回-1作为错误提示
}
return list.getFirst();
}
// 检查队列是否为空
public boolean isEmpty() {
return list.isEmpty();
}
}
4. 使用队列
下面是如何使用这个队列类来执行基本操作的例子:
public class QueueDemo {
public static void main(String[] args) {
MyQueue queue = new MyQueue();
// 入队操作
queue.enqueue(10);
queue.enqueue(20);
queue.enqueue(30);
// 查看队首元素
System.out.println("队首元素: " + queue.peek()); // 输出队首元素: 10
// 出队操作并打印
System.out.println("出队元素: " + queue.dequeue()); // 输出出队元素: 10
System.out.println("出队元素: " + queue.dequeue()); // 输出出队元素: 20
// 继续操作
queue.enqueue(40);
System.out.println("出队元素: " + queue.dequeue()); // 输出出队元素: 30
System.out.println("出队元素: " + queue.dequeue()); // 输出出队元素: 40
// 检查队列是否为空
System.out.println("队列是否为空: " + queue.isEmpty()); // 输出队列是否为空: true
}
}
5.基本操作
如果你想要将队列中的一个值赋给另一个变量,但不希望从队列中移除这个值,你应该使用 peek()
方法。这个方法会返回队列头部的元素,但不会从队列中移除这个元素。
以下是如何实现的示例:
import java.util.LinkedList;
import java.util.Queue;
public class Example {
public static void main(String[] args) {
// 创建一个队列并添加元素
Queue<Integer> queue = new LinkedList<>();
queue.add(10);
queue.add(20);
queue.add(30);
// 使用peek()方法获取队列头部的元素但不移除它
Integer topElement = queue.peek();
// 输出赋值后的变量
System.out.println("队列头部的元素赋给变量: " + topElement);
// 输出队列确保队列头部元素未被移除
System.out.println("队列的当前状态: " + queue);
}
}
输出
队列头部的元素赋给变量: 10
队列的当前状态: [10, 20, 30]
注意
- 使用
peek()
方法时,如果队列为空,则该方法返回null
。 - 如果你想要从队列中移除并获取元素,则应使用
poll()
方法。poll()
方法在移除并返回队列的头部元素后,队列的状态将更新。
在实际应用中,选择peek()
或poll()
取决于你是否需要从队列中移除元素。
要计算队列中所有数的和,你可以遍历队列并累加每个元素的值。在Java中,可以使用增强型for循环或者迭代器来遍历队列。以下是使用增强型for循环计算队列中所有数之和的示例:
import java.util.LinkedList;
import java.util.Queue;
public class Example {
public static void main(String[] args) {
// 创建一个队列并添加元素
Queue<Integer> queue = new LinkedList<>();
queue.add(10);
queue.add(20);
queue.add(30);
// 计算队列中所有数之和
int sum = 0;
for (int num : queue) {
sum += num;
}
// 输出总和
System.out.println("队列中所有数之和: " + sum);
}
}
输出
队列中所有数之和: 60
另一种方法:使用迭代器
如果你更倾向于使用迭代器,这里也提供了一个示例代码:
import java.util.LinkedList;
import java.util.Queue;
import java.util.Iterator;
public class Example {
public static void main(String[] args) {
// 创建一个队列并添加元素
Queue<Integer> queue = new LinkedList<>();
queue.add(10);
queue.add(20);
queue.add(30);
// 使用迭代器计算队列中所有数之和
int sum = 0;
Iterator<Integer> iterator = queue.iterator();
while (iterator.hasNext()) {
sum += iterator.next();
}
// 输出总和
System.out.println("队列中所有数之和: " + sum);
}
}
这两种方法都能达到相同的目的,你可以根据自己的偏好选择使用。
要让队列中的元素从大到小排列,你需要将队列中的元素排序。由于Queue
接口在Java中没有直接提供排序功能,你通常需要将队列元素转移到一个可以排序的中间数据结构中,比如ArrayList
或者数组,使用这些数据结构提供的排序函数,然后再将排序后的元素重新放回队列。
以下是使用ArrayList
来对队列元素进行排序的示例:
import java.util.LinkedList;
import java.util.Queue;
import java.util.ArrayList;
import java.util.Collections;
public class Example {
public static void main(String[] args) {
// 创建一个队列并添加元素
Queue<Integer> queue = new LinkedList<>();
queue.add(10);
queue.add(20);
queue.add(30);
// 将队列元素转移到ArrayList中
ArrayList<Integer> list = new ArrayList<>(queue);
// 对ArrayList中的元素进行排序,然后反转以满足从大到小的要求
Collections.sort(list);
Collections.reverse(list);
// 清空原队列
queue.clear();
// 将排序后的元素重新放回队列
queue.addAll(list);
// 输出排序后的队列
System.out.println("从大到小排序后的队列: " + queue);
}
}
输出
从大到小排序后的队列: [30, 20, 10]
注意
- 这种方法会改变原队列的元素顺序。如果你不想改变原队列,可以先克隆原队列,然后对克隆进行操作。
- 对于大数据集,这种排序方法可能不是最高效的,因为它涉及到多次数据结构之间的转换。如果性能是关键考虑因素,可能需要考虑使用更适合大量数据排序的算法或数据结构。
Collections.sort()
默认按照升序排序,所以在排序后需要使用Collections.reverse()
来反转列表,以达到从大到小的顺序。
6.优先队列
优先队列学习笔记
1. 什么是优先队列?
优先队列(Priority Queue)是一种特殊的队列,其中每个元素都有一个优先级。优先级最高的元素总是位于队列的前端,并且每次出队操作都会移除优先级最高的元素。
2. 优先队列的特点
- 优先级:元素按照优先级排序,而不是按照入队的顺序。
- 出队顺序:总是优先级最高的元素先出队。
- 实现方式:通常使用堆(Heap)数据结构来实现。
3. 优先队列的应用场景
- 任务调度:操作系统中的任务调度,优先级高的任务先执行。
- 数据压缩:如Huffman编码。
4. Java中的优先队列
Java中提供了PriorityQueue
类,位于java.util
包中。PriorityQueue
默认是一个最小堆(即优先级最小的元素在队列前端),但可以通过提供自定义的比较器(Comparator)来实现最大堆。
5. 代码示例
以下是一个简单的Java代码示例,展示了如何使用PriorityQueue
。
import java.util.PriorityQueue;
import java.util.Comparator;
public class PriorityQueueExample {
public static void main(String[] args) {
// 默认是最小堆
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
// 添加元素
minHeap.add(10);
minHeap.add(30);
minHeap.add(20);
minHeap.add(5);
// 输出元素(注意:这里不会按优先级顺序输出)
System.out.println("Min Heap elements (not sorted): " + minHeap);
// 出队操作
System.out.println("Dequeue elements from Min Heap:");
while (!minHeap.isEmpty()) {
System.out.println(minHeap.poll());
}
// 创建一个最大堆
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
// 添加元素
maxHeap.add(10);
maxHeap.add(30);
maxHeap.add(20);
maxHeap.add(5);
// 输出元素(注意:这里不会按优先级顺序输出)
System.out.println("Max Heap elements (not sorted): " + maxHeap);
// 出队操作
System.out.println("Dequeue elements from Max Heap:");
while (!maxHeap.isEmpty()) {
System.out.println(maxHeap.poll());
}
}
}
6. 自定义比较器
如果你需要根据自定义的规则来确定优先级,可以实现一个Comparator
接口。
import java.util.PriorityQueue;
import java.util.Comparator;
class Task {
String name;
int priority;
Task(String name, int priority) {
this.name = name;
this.priority = priority;
}
@Override
public String toString() {
return name + " (" + priority + ")";
}
}
public class CustomPriorityQueueExample {
public static void main(String[] args) {
// 自定义比较器
Comparator<Task> taskComparator = new Comparator<Task>() {
@Override
public int compare(Task t1, Task t2) {
return t2.priority - t1.priority; // 优先级高的在前
}
};
PriorityQueue<Task> taskQueue = new PriorityQueue<>(taskComparator);
// 添加任务
taskQueue.add(new Task("Task 1", 3));
taskQueue.add(new Task("Task 2", 1));
taskQueue.add(new Task("Task 3", 2));
// 出队操作
System.out.println("Dequeue tasks:");
while (!taskQueue.isEmpty()) {
System.out.println(taskQueue.poll());
}
}
}
7. 总结
队列是一个非常实用的数据结构,适用于多种需要按照元素进入顺序处理数据的场景。了解队列的基本操作和实现可以帮助你更好地理解数据结构的应用,为解决更复杂的问题打下基础。在Java中实现队列的方法很多,这里我们使用了简单直观的LinkedList来完成我们的队列。优先队列是一种非常有用的数据结构,适用于需要按照优先级处理元素的场景。Java中的PriorityQueue
类提供了方便的接口来实现优先队列,并且可以通过自定义比较器来灵活地控制元素的优先级。。