一.队列定义
在 java 中,队列(queue) 是一种遵循 先进先出(fifo) 原则的数据结构,可以通过
java.util.queue
接口及其实现类来使用。
二.常见接口
添加元素:
boolean add(e e)
: 添加元素,若队列满则抛出异常。boolean offer(e e)
: 添加元素,队列满时返回false
。
移除元素:
e remove()
: 移除并返回队首元素,队列空时抛出异常。e poll()
: 移除并返回队首元素,队列空时返回null
。
查看队首元素:
e element()
: 返回队首元素但不移除,队列空时抛出异常。e peek()
: 返回队首元素但不移除,队列空时返回null
。
三.常见实现类
3.1 arraydeque
3.1.1 实现原理
* 基于数组进行实现
* 不允许添加null元素
* 在两端插入和删除元素的性能较好,时间复杂度为o(1)
* 没有容量限制,会根据需要自动扩容。
3.1.2 方法图解
3.1.3 demo代码
public class arraydequedemo { public static void main(string[] args) throws exception{ arraydeque<integer> deque = new arraydeque<>(); for(int i = 7 ; i >=0 ; i--){ deque.addfirst(i); } for (int i = 8 ; i < 15 ; i++){ deque.addlast(i); } show(deque); deque.addlast(15); show(deque); } public static void show(arraydeque<integer> deque) throws exception{ field elements = arraydeque.class.getdeclaredfield("elements"); elements.setaccessible(true); system.out.println(jsonobject.tojsonstring(elements.get(deque))); system.out.println(((object[])( elements.get(deque))).length); field head = arraydeque.class.getdeclaredfield("head"); head.setaccessible(true); system.out.println(jsonobject.tojsonstring(head.get(deque))); field tail = arraydeque.class.getdeclaredfield("tail"); tail.setaccessible(true); system.out.println(jsonobject.tojsonstring(tail.get(deque))); } }
3.2 linkedlist
3.1.1 实现原理
* 基于链表实现
* 允许添加null元素
* 在插入和删除元素时性能较好,时间复杂度为o(1)
3.1.2 demo代码
public class linkedlistdemo { public static void main(string[] args) { linkedlist<integer> queue = new linkedlist<>(); for(int i = 0 ; i < 20 ; i++){ queue.add((int)(math.random()*1000)); queue.addfirst(i); queue.addlast(i); } while (!queue.isempty()){ system.out.println(queue.poll()); } system.out.println(queue.poll()); } }
3.3 priorityqueue
3.1.1 实现原理
* 基于二叉堆(通常是最小堆)实现
3.1.2 demo代码
public class priorityqueuedemo { public static void main(string[] args) { priorityqueue<integer> queue = new priorityqueue<>(integer::compareto); for(int i = 0 ; i < 20 ; i++){ queue.add((int)(math.random()*1000)); } while (!queue.isempty()){ system.out.println(queue.poll()); } system.out.println(queue.poll()); } }
3.1.3 最小堆demo代码
class minheap{ private final list<integer> heap; public minheap(){ heap = new arraylist<>(); } //左子节点 private int leftchild(int i){ return 2*i+1; } //右子节点 private int rightchild(int i){ return 2*i+2; } //父节点 private int parent(int i){ return (i-1)/2; } //插入节点 public void insert(int x){ heap.add(x); int index = heap.size()-1; //上浮节点 while(index > 0 && heap.get(index) < heap.get(parent(index))){ swap(index, parent(index)); index = parent(index); } } //交换节点 private void swap(int i, int j) { int temp = heap.get(i); heap.set(i, heap.get(j)); heap.set(j, temp); } //删除最小节点 public int deletemin(){ if(heap.isempty()){ throw new runtimeexception("堆为空"); } if (heap.size() == 1){ return heap.remove(0); } int min = heap.get(0); heap.set(0,heap.remove(heap.size()-1)); minheapify(0); return min; } //更新指定节点的最小树 public void minheapify(int i){ //左子节点 int left = leftchild(i); //右子节点 int right = rightchild(i); //最小节点 int smallest = i; //计算左节点 if(left < heap.size() && heap.get(left) < heap.get(smallest)){ smallest = left; } //计算右节点 if(right < heap.size() && heap.get(right) < heap.get(smallest)){ smallest = right; } if (smallest != i){ swap(i, smallest); minheapify(smallest); } } }
3.4 优缺点
实现类 | 优点 | 缺点 | 使用场景 |
---|---|---|---|
linkedlist | 1.支持双端操作 2.动态扩容,无容量限制 | 1.非线程安全 2.链表结构导致内存占用较高 | 1.需要双端队列操作(如栈或队列) 2.单线程环境下需要快速插入/删除 |
arraydeque | 1.基于数组实现,内存连续,访问效率高 2.默认初始容量较小,动态扩容效率优于 | 1.非线程安全 2.容量固定时扩容需要复制数组 | 1.高频次队列操作(如广度优先搜索) 2.替代 |
priorityqueue | 1.元素按优先级排序 2.基于堆结构,插入/删除时间复杂度为 | 1.非线程安全 2.遍历顺序不保证按优先级排序 | 1.任务调度(按优先级处理) 2.合并多个有序数据流。 |
总结
到此这篇关于java中常见队列的文章就介绍到这了,更多相关java常见队列内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论