
Java 的 PriorityQueue 底层用的是**最小堆(Min-Heap)**,基于数组实现的完全二叉树结构,不使用链表或显式的树节点。它默认按自然顺序排序(即最小元素优先出队),支持自定义比较器来改变优先级逻辑。
堆的数组表示与父子关系
PriorityQueue 内部维护一个 Object[] queue 数组,索引从 0 开始。完全二叉树的父子关系通过下标公式隐式表达:
- 对于索引为 i 的节点,其左子节点在 2*i + 1
- 右子节点在 2*i + 2
- 父节点在 (i - 1) / 2(整除)
这种映射让树结构无需指针就能高效定位,也保证了内存连续、缓存友好。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
插入(offer/add)时的上浮(siftUp)
新元素加到数组末尾,然后不断和父节点比较:如果比父小(最小堆),就交换,继续向上;直到满足堆序性质或到达根。
- 时间复杂度:O(log n)
- 关键操作是
siftUp(int k, E x),k 是插入位置,x 是待插入元素 - 比较依赖
Comparator或元素的compareTo()
删除头部(poll)时的下沉(siftDown)
取出索引 0 的元素后,把最后一个元素移到堆顶,再让它“下沉”:和两个子节点中更小的那个比较,若比它大,就交换;重复直到满足堆序或无子节点。
- 时间复杂度:O(log n)
- 核心方法是
siftDown(int k, E x),k 是起始位置(通常是 0) - 注意:只和较小的子节点比(维持最小堆),不是和任意子节点交换
不是严格意义上的“二叉堆”,但行为一致
PriorityQueue 并未直接继承或封装一个独立的 Heap 类,而是把堆操作逻辑(siftUp/siftDown)内联在自己的增删方法中。它还做了些实用优化:
- 初始容量为 11,扩容策略是 oldCapacity + (oldCapacity >> 1),即约 1.5 倍增长
- 允许 null 元素(仅当使用自定义 Comparator 且明确处理 null 时)
- 不保证遍历时有序——
iterator()返回的顺序是数组原始顺序,不是堆序
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










