Java 语言 堆排序基础 二叉堆的构建与元素提取

Java阿木 发布于 2025-06-25 8 次阅读


Java语言中的堆排序:二叉堆的构建与元素提取

堆排序是一种基于比较的排序算法,它利用了二叉堆这种数据结构。二叉堆是一种特殊的完全二叉树,它满足堆性质:对于任意节点i(除了根节点),其父节点i的值总是大于或等于(在最大堆中)或小于或等于(在最小堆中)其子节点的值。本文将围绕Java语言,详细介绍二叉堆的构建与元素提取过程。

一、二叉堆的构建

在Java中,我们可以通过实现一个自定义的类来表示二叉堆。以下是一个简单的二叉堆实现:

java

public class MaxHeap {


private int[] heap;


private int size;


private int capacity;

public MaxHeap(int capacity) {


this.capacity = capacity;


this.size = 0;


this.heap = new int[capacity];


}

private int parent(int i) {


return (i - 1) / 2;


}

private int leftChild(int i) {


return (2 i + 1);


}

private int rightChild(int i) {


return (2 i + 2);


}

private boolean isLeaf(int i) {


return (i > (size / 2)) && (i <= size);


}

private void swap(int f, int s) {


int temp = heap[f];


heap[f] = heap[s];


heap[s] = temp;


}

public void insert(int element) {


if (size >= capacity) {


return;


}


size++;


int i = size - 1;


heap[i] = element;

while (i != 0 && heap[parent(i)] < heap[i]) {


swap(parent(i), i);


i = parent(i);


}


}

public void buildHeap() {


for (int i = (size / 2) - 1; i >= 0; i--) {


heapify(i);


}


}

private void heapify(int i) {


if (isLeaf(i)) {


return;


}

if (heap[leftChild(i)] > heap[i] || heap[rightChild(i)] > heap[i]) {


if (heap[leftChild(i)] > heap[rightChild(i)]) {


swap(i, leftChild(i));


heapify(leftChild(i));


} else {


swap(i, rightChild(i));


heapify(rightChild(i));


}


}


}


}


在上面的代码中,我们定义了一个`MaxHeap`类,它包含了一个整型数组`heap`来存储堆中的元素,以及一些辅助方法来操作堆。`insert`方法用于向堆中插入一个新元素,而`buildHeap`方法用于将一个无序数组转换成最大堆。

二、元素提取

在堆排序中,我们通常需要从堆中提取元素。以下是如何从最大堆中提取元素的方法:

java

public int extractMax() {


if (size <= 0) {


return Integer.MIN_VALUE;


}


if (size == 1) {


size--;


return heap[0];


}

int root = heap[0];


heap[0] = heap[size - 1];


size--;


heapify(0);

return root;


}


在上面的代码中,`extractMax`方法用于从最大堆中提取最大元素。它首先检查堆是否为空或只有一个元素,然后交换根节点和最后一个元素,减少堆的大小,并调用`heapify`方法来恢复堆的性质。

三、堆排序算法

堆排序算法的基本思想是:首先将一个无序数组转换成最大堆,然后重复执行以下步骤:

1. 提取堆顶元素(最大元素)。

2. 将堆顶元素与堆的最后一个元素交换。

3. 减少堆的大小。

4. 调用`heapify`方法来恢复堆的性质。

以下是堆排序算法的Java实现:

java

public class HeapSort {


public static void sort(int[] array) {


MaxHeap maxHeap = new MaxHeap(array.length);

// 构建最大堆


for (int i = 0; i < array.length; i++) {


maxHeap.insert(array[i]);


}

// 提取堆顶元素并重建堆


for (int i = array.length - 1; i >= 0; i--) {


array[i] = maxHeap.extractMax();


}


}

public static void main(String[] args) {


int[] array = {12, 11, 13, 5, 6, 7};


sort(array);

System.out.println("Sorted array is:");


for (int i = 0; i < array.length; i++) {


System.out.print(array[i] + " ");


}


}


}


在上面的代码中,`sort`方法首先构建一个最大堆,然后重复提取堆顶元素,直到堆为空。我们得到了一个排序后的数组。

四、总结

本文介绍了Java语言中二叉堆的构建与元素提取过程,并展示了如何使用堆排序算法对数组进行排序。通过理解二叉堆的性质和操作,我们可以有效地实现堆排序,它是一种时间复杂度为O(n log n)的排序算法,适用于大规模数据的排序。