java中priorityqueue默认基于二叉小顶堆实现,底层用数组模拟完全二叉树,通过下标关系(左=2i+1、右=2i+2、父=(i-1)/2)维护堆序,支持o(log n)插入(siftup)和删除(siftdown),并可通过comparator自定义排序规则。

Java 中的 PriorityQueue 默认就是基于**二叉小顶堆(min-heap)**实现的,它不直接暴露底层结构,但内部用数组模拟完全二叉树,通过父子节点下标关系维护堆序性。
小顶堆的存储结构:数组模拟完全二叉树
PriorityQueue 底层是一个动态扩容的 Object 数组(queue),索引从 0 开始。对于任意节点索引 i:
- 左孩子索引 =
2 * i + 1 - 右孩子索引 =
2 * i + 2 - 父节点索引 =
(i - 1) / 2(整除)
这种映射保证了树的“完全二叉”形态,也使得插入、删除能在 O(log n) 时间内完成。
插入元素:上浮(siftUp)维持小顶堆性质
调用 offer() 或 add() 时,新元素先放在数组末尾,然后不断与父节点比较:若比父小,就交换位置,直到满足“父 ≤ 子”。
例如插入 3、1、4、1(重复允许):
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 插 3 → [3]
- 插 1 → [3,1] → 上浮:1 比 3 小 → 交换 → [1,3]
- 插 4 → [1,3,4](已满足堆序)
- 插 1 → [1,3,4,1] → 上浮:1 比父(3)小 → 交换 → [1,1,4,3]
获取/弹出最小值:下沉(siftDown)恢复堆结构
poll() 总是返回并移除堆顶(即数组第一个元素),然后把最后一个元素移到堆顶,再向下调整:
- 比较当前节点与两个子节点中的较小者
- 若当前节点大于该较小值,则交换;继续下沉,直到不再违反小顶堆性质
比如从 [1,1,4,3] 中 poll():
- 返回 1,剩余 [3,1,4](先挪末尾 3 到堆顶)
- 3 比左右子(1 和 4)都大 → 与左子 1 交换 → [1,3,4]
- 此时已满足堆序
自定义排序:传入 Comparator 构造小顶堆或大顶堆
默认构造器使用元素自然顺序(要求实现 Comparable),也可传入 Comparator 改变比较逻辑:
- 小顶堆(升序):
new PriorityQueue(Comparator.naturalOrder()) - 大顶堆(降序):
new PriorityQueue(Comparator.reverseOrder()) - 按字符串长度小顶堆:
new PriorityQueue((a, b) -> a.length() - b.length())
注意:Comparator 定义的是“谁优先”,不是“是否交换”。只要保证 compare(a,b) 表示 a 应排在 b 前面(即 a 优先级更高),PriorityQueue 就会把它放在更靠近堆顶的位置。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










