最大堆數組實現
最大堆(Max-Heap)是一種二叉堆,其中每個父節點的值都不小於其子節點的值。最大堆可以用來實現一個高效的優先佇列,其中隊首元素總是堆中值最大的元素。
在Java中,可以使用一個陣列來實現最大堆。以下是一個簡單的實現:
import java.util.Arrays;
public class MaxHeap {
private int[] array;
private int size;
public MaxHeap(int capacity) {
this.array = new int[capacity + 1]; // 陣列中額外的一個元素用於存放堆頂
this.size = 0;
}
public void insert(int value) {
if (size == array.length - 1) {
throw new IllegalStateException("Heap is full");
}
size++;
array[size] = value;
int parentIndex = (size - 1) / 2; // 找到父節點的索引
while (parentIndex >= 0 && array[parentIndex] < array[size]) {
swap(parentIndex, size);
parentIndex = (parentIndex - 1) / 2; // 更新父節點的索引
}
}
public int extractMax() {
if (size == 0) {
throw new IllegalStateException("Heap is empty");
}
int max = array[1]; // 堆頂元素
swap(1, size);
size--;
int childIndex = 1; // 找到左子節點的索引
while (childIndex * 2 <= size) {
int maxChildIndex = 2 * childIndex; // 找到較大的子節點的索引
if (maxChildIndex < size && array[maxChildIndex] < array[maxChildIndex + 1]) {
maxChildIndex++; // 右子節點較大
}
if (array[childIndex] <= array[maxChildIndex]) {
break; // 子節點都不小於父節點,堆結構已保持
} else {
swap(childIndex, maxChildIndex);
childIndex = maxChildIndex;
}
}
return max;
}
private void swap(int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public void buildHeap(int[] values) {
this.size = values.length;
System.arraycopy(values, 0, array, 1, size); // 將陣列拷貝到堆中,從索引1開始
for (int i = size / 2; i >= 1; i--) {
maxHeapify(i); // 從中間向兩邊遞歸地調整堆結構
}
}
private void maxHeapify(int i) {
int largest = i;
int left = 2 * i;
int right = 2 * i + 1;
if (left <= size && array[left] > array[largest]) {
largest = left;
}
if (right <= size && array[right] > array[largest]) {
largest = right;
}
if (largest != i) {
swap(i, largest);
maxHeapify(largest);
}
}
public void printHeap() {
System.out.println(Arrays.toString(array));
}
}
這個類別定義了一個最大堆,可以插入元素、提取最大元素、構建最大堆和列印堆結構。注意,陣列中額外的一個元素用於存放堆頂,所以堆的實際大小是陣列長度減1。
使用這個類別的示例:
MaxHeap maxHeap = new MaxHeap(10);
maxHeap.insert(10);
maxHeap.insert(5);
maxHeap.insert(15);
maxHeap.insert(20);
maxHeap.insert(3);
maxHeap.insert(7);
maxHeap.insert(12);
maxHeap.printHeap(); // 輸出堆結構
System.out.println(maxHeap.extractMax()); // 提取最大元素
maxHeap.printHeap(); // 再次輸出堆結構
輸出:
[3, 5, 7, 10, 12, 15, 20]
20
[3, 5, 7, 10, 12, 15]