在Java中,可以通过实现自己的最大堆数据结构或修改现有的PriorityQueue
来实现最大堆。Java的PriorityQueue
类是基于优先级堆实现的,其默认行为是最小堆。为了使其表现为最大堆,我们可以提供一个自定义比较器来逆转排序顺序。
以下是使用Java内置PriorityQueue
实现最大堆的示例:
import java.util.Comparator;
import java.util.PriorityQueue;
public class MaxHeapExample {
public static void main(String[] args) {
// 使用自定义比较器实现最大堆
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
// 添加元素到堆
maxHeap.offer(3);
maxHeap.offer(1);
maxHeap.offer(4);
maxHeap.offer(1);
maxHeap.offer(5);
maxHeap.offer(9);
maxHeap.offer(2);
maxHeap.offer(6);
maxHeap.offer(5);
maxHeap.offer(3);
// 提取最大元素(堆顶元素)
System.out.println("Max Value: " + maxHeap.poll()); // 输出 9
// 继续提取最大元素
while (!maxHeap.isEmpty()) {
System.out.println(maxHeap.poll());
}
}
}
如果你想手动实现一个最大堆,你可以创建一个类,其中包含一个数组以及方法来维护堆的性质(如添加元素、提取最大元素等)。以下是一个手动实现的最大堆的简单示例:
public class MaxHeap {
private int[] heap;
private int size;
private int maxSize;
public MaxHeap(int maxSize) {
this.maxSize = maxSize;
this.size = 0;
heap = new int[this.maxSize];
}
private int parent(int pos) {
return (pos - 1) / 2;
}
private int leftChild(int pos) {
return (2 * pos) + 1;
}
private int rightChild(int pos) {
return (2 * pos) + 2;
}
private void swap(int fpos, int spos) {
int tmp = heap[fpos];
heap[fpos] = heap[spos];
heap[spos] = tmp;
}
private void maxHeapify(int pos) {
if (!isLeaf(pos)) {
if (heap[pos] < heap[leftChild(pos)] || heap[pos] < heap[rightChild(pos)]) {
if (heap[leftChild(pos)] > heap[rightChild(pos)]) {
swap(pos, leftChild(pos));
maxHeapify(leftChild(pos));
} else {
swap(pos, rightChild(pos));
maxHeapify(rightChild(pos));
}
}
}
}
private boolean isLeaf(int pos) {
return pos >= (size / 2) && pos < size;
}
public void insert(int element) {
if (size >= maxSize) {
return;
}
heap[size] = element;
int current = size;
size++;
while (heap[current] > heap[parent(current)]) {
swap(current, parent(current));
current = parent(current);
}
}
public int extractMax() {
if (size == 0) {
throw new IllegalStateException("Heap is empty");
}
int popped = heap[0];
heap[0] = heap[--size];
maxHeapify(0);
return popped;
}
// 调用示例
public static void main(String[] args) {
MaxHeap maxHeap = new MaxHeap(10);
maxHeap.insert(3);
maxHeap.insert(1);
maxHeap.insert(4);
maxHeap.insert(1);
maxHeap.insert(5);
maxHeap.insert(9);
maxHeap.insert(2);
maxHeap.insert(6);
maxHeap.insert(5);
maxHeap.insert(3);
// 提取最大元素(堆顶元素)
System.out.println("Max Value: " + maxHeap.extractMax()); // 输出 9
// 继续提取最大元素
while (maxHeap.size > 0) {
System.out.println(maxHeap.extractMax());
}
}
}
在这个手动实现的最大堆中,我们使用数组来存储堆结构。insert()
方法用于添加新元素到堆中,它会从堆的底部开始,并确保堆的性质通过与父节点比较并在必要时交换位置。extractMax()
方法用于提取并删除堆中的最大元素,即数组的第一个元素,并重新调整堆的结构以保持最大堆的性质。maxHeapify()
是一个重要的辅助方法,它用于在提取元素后重新整理堆的结构。