赞
踩
双端队列(Deque,全名为"Double Ended Queue")是Java集合框架中的一种数据结构,它允许在队列两端进行元素的插入和删除操作。Deque可以看作是既支持队列操作,又支持栈操作的一种数据结构,因为它同时具有FIFO(First-In-First-Out)和LIFO(Last-In-First-Out)的特性。在Java中,Deque接口位于java.util包中,它的实现类有ArrayDeque
和LinkedList
。
Deque接口继承自Queue接口,因此它包含了Queue的所有方法,并在此基础上添加了一些特有的方法。下面是一些常用的Deque接口方法:
void addFirst(E e)
:在队列的头部插入元素。void addLast(E e)
:在队列的尾部插入元素。boolean offerFirst(E e)
:尝试在队列头部插入元素,如果成功返回true,否则返回false。boolean offerLast(E e)
:尝试在队列尾部插入元素,如果成功返回true,否则返回false。E removeFirst()
:移除并返回队列头部的元素,如果队列为空,则抛出异常。E removeLast()
:移除并返回队列尾部的元素,如果队列为空,则抛出异常。E pollFirst()
:移除并返回队列头部的元素,如果队列为空,则返回null。E pollLast()
:移除并返回队列尾部的元素,如果队列为空,则返回null。E getFirst()
:返回队列头部的元素,但不移除,如果队列为空,则抛出异常。E getLast()
:返回队列尾部的元素,但不移除,如果队列为空,则抛出异常。E peekFirst()
:返回队列头部的元素,但不移除,如果队列为空,则返回null。E peekLast()
:返回队列尾部的元素,但不移除,如果队列为空,则返回null。ArrayDeque
是基于数组实现的双端队列,它不支持null元素,并且容量可以动态扩展。由于基于数组实现,它在随机访问和插入/删除操作上的性能都比较好。下面是一个使用ArrayDeque
实现的窗口滑动最大值问题的示例:
import java.util.*;
public class ArrayDequeExample {
public static void main(String[] args) {
int[] nums = {1, 3, -1, -3, 5, 3, 6, 7};
int k = 3;
Deque<Integer> deque = new ArrayDeque<>();
int[] result = new int[nums.length - k + 1];
for (int i = 0; i < nums.length; i++) {
while (!deque.isEmpty() && deque.peekFirst() < i - k + 1) {
deque.removeFirst(); // 移除超出窗口范围的元素
}
while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
deque.removeLast(); // 保持队列中元素递减
}
deque.addLast(i); // 将当前元素加入队列尾部
if (i >= k - 1) {
result[i - k + 1] = nums[deque.peekFirst()]; // 窗口内的最大值
}
}
System.out.println(Arrays.toString(result)); // 输出结果
}
}
LinkedList
同样实现了Deque接口,基于双向链表实现,支持null元素。由于是链表实现,LinkedList
在插入/删除操作上相对快速,但随机访问的性能较差。下面是一个使用LinkedList
实现的Undo/Redo功能的示例:
import java.util.*;
public class LinkedListExample {
public static void main(String[] args) {
LinkedList<String> history = new LinkedList<>();
String currentText = "";
// 模拟编辑操作
history.add(currentText);
currentText = "Hello";
history.add(currentText);
currentText = "Hello, World!";
history.add(currentText);
// 撤销操作
currentText = history.removeLast(); // 恢复到"Hello"状态
// 重做操作
currentText = history.removeLast(); // 恢复到初始状态
}
}
双端队列在许多场景下都非常有用,例如:
ConcurrentLinkedDeque
实现线程安全的双端队列。双端队列(Deque)是Java集合框架中一个功能强大的数据结构,它支持在队列两端进行插入和删除操作,具备队列和栈的特性。通过ArrayDeque和LinkedList这两个实现类,可以根据实际需求选择合适的双端队列来解决问题。在编写代码时,根据具体场景选择不同的Deque实现,可以提高代码的效率和可读性。
希望这篇文章对你理解和使用Java中的双端队列有所帮助!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。