【深入浅出】Java 优先队列 PriorityQueue
-
基本概念
- PriorityQueue:优先队列,Java中优先队列保证每次取出元素的权值是队列中最小的,而CPP中是最大的。
- 关于该队列内部的元素大小比较,可以根据元素本身自然顺序或者使用构造函数中传入的比较器函数。
- PriorityQueue实现了Queue接口,但不允许空元素进入队列
-
底层实现
- Java 中 PriorityQueue的底层数据结构是基于完全二叉树实现的小顶堆。
- 完全二叉树:叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部
- 小顶堆:即按照根值<左节点值<右节点值 的规则分配元素。
- 用最小堆实现的特性
- 对于节点node,它的父节点:pNode=(node-1)/2
- 左子节点:leftNode=node*2+1
- 右子节点:rightNode=node*2+2
- Java 中 PriorityQueue的底层数据结构是基于完全二叉树实现的小顶堆。
-
方法源码剖析
-
offer()
-
offer()和add()在优先队列中有什么区别呢?区别在于返回形式,add()方法插入失败时进入异常体系处理,而offer()则是返回true/false。
-
调整函数siftUp():帮助小顶堆维护
-
源码分析:
public boolean offer(E e) { //小顶堆元素不能为空 if (e == null) throw new NullPointerException(); //midCount是记录该优先队列被修改的次数 modCount++; int i = size; if (i >= queue.length) grow(i + 1);//自动扩容 size = i + 1; if (i == 0)//队列原来为空,这是插入的第一个元素 queue[0] = e; else siftUp(i, e);//调整 return true; } private void siftUp(int k, E x) { while (k > 0) { //ptNo = (node-1)/2 int parent = (k - 1) >>> 1; Object e = queue
-
-