最小堆的定义
最小堆是一种特殊的完全二叉树,属于堆数据结构的一种。它具有以下两个关键特性:
- 结构性:最小堆是一棵完全二叉树,这意味着除了最后一层外,每一层都被完全填充,并且最后一层的节点从左到右依次排列。
- 有序性:对于堆中的任意节点,其值都小于或等于它的子节点的值。也就是说,根节点存储的是堆中的最小值。
以下是一个简单的最小堆示例:
1
/ \
2 3
/ \ / \
4 5 6 7
在这个最小堆中,根节点 1 是最小值,且每个节点的值都小于其子节点的值。
Java 中 PriorityQueue 是最小堆的原因
在 Java 里,PriorityQueue 默认是一个最小堆。这是由它的设计和实现所决定的:
- 默认比较器:
PriorityQueue在创建时如果没有指定比较器,会使用元素的自然顺序。对于实现了Comparable接口的元素,会按照其compareTo方法的规则进行排序,从而保证队列头部(也就是堆的根节点)是最小元素。 - 插入和删除操作的实现:
PriorityQueue的插入和删除操作会维护堆的有序性。当插入一个新元素时,会将其放在堆的末尾,然后通过上浮操作调整堆结构,确保新元素被放到合适位置;删除元素时,通常是删除堆顶元素,之后会将堆的最后一个元素移到堆顶,再通过下沉操作重新调整堆结构。
下面是一个简单的 Java 代码示例,展示了 PriorityQueue 作为最小堆的使用:
import java.util.PriorityQueue;
public class MinHeapExample {
public static void main(String[] args) {
// 创建一个 PriorityQueue 实例
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
// 向堆中添加元素
minHeap.add(3);
minHeap.add(1);
minHeap.add(2);
// 依次取出堆顶元素
while (!minHeap.isEmpty()) {
System.out.println(minHeap.poll());
}
}
}
在上述代码中,我们创建了一个 PriorityQueue 实例,向其中添加了 3 个元素。当我们依次取出堆顶元素时,输出的顺序是 1、2、3,这表明 PriorityQueue 确实是按照最小堆的规则进行排序的。