一.堆排序(Heap Sort)是一种基于比较的排序算法,利用堆这种数据结构来实现。堆是一种特殊的完全二叉树,分为最大堆和最小堆。堆排序通常使用最大堆来实现升序排序。以下是用Java实现堆排序的代码及其详细讲解。
二.堆排序代码
public class HeapSort {
public static void heapSort(int[] array) {
int n = array.length;
// 构建最大堆
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(array, n, i);
}
// 一个个从堆中取出元素
for (int i = n - 1; i > 0; i--) {
// 将当前根(最大值)与末尾元素交换
int temp = array[0];
array[0] = array[i];
array[i] = temp;
// 调整堆
heapify(array, i, 0);
}
}
private static void heapify(int[] array, int n, int i) {
int largest = i; // 初始化最大值为根节点
int left = 2 * i + 1; // 左子节点
int right = 2 * i + 2; // 右子节点
// 如果左子节点大于根节点
if (left < n && array[left] > array[largest]) {
largest = left;
}
// 如果右子节点大于最大值
if (right < n && array[right] > array[largest]) {
largest = right;
}
// 如果最大值不是根节点
if (largest != i) {
int swap = array[i];
array[i] = array[largest];
array[largest] = swap;
// 递归地调整受影响的子树
heapify(array, n, largest);
}
}
public static void main(String[] args) {
int[] array = {12, 11, 13, 5, 6, 7};
System.out.println("Unsorted array:");
printArray(array);
heapSort(array);
System.out.println("Sorted array:");
printArray(array);
}
private static void printArray(int[] array) {
for (int value : array) {
System.out.print(value + " ");
}
System.out.println();
}
}
三.详细讲解
- 构建最大堆:
- 从最后一个非叶子节点开始,向上调整堆。
- heapify方法用于维护堆的性质,确保父节点大于或等于其子节点。
- 堆化过程:
- heapify方法接受三个参数:数组、堆的大小n、当前节点i。
- 初始化largest为当前节点i。
- 计算左子节点left和右子节点right。
- 比较当前节点与其子节点,找出最大值的索引。
- 如果最大值不是当前节点,交换它们,并递归地调整受影响的子树。
- 排序过程:
- 将堆顶元素(最大值)与末尾元素交换。
- 减少堆的大小,并调用heapify方法调整堆。
- 重复此过程,直到堆的大小为1。
- 时间复杂度:
- 堆排序的时间复杂度为O(n log n),因为构建堆的时间复杂度为O(n),每次调整堆的时间复杂度为O(log n)。
- 空间复杂度:
- 堆排序的空间复杂度为O(1),因为它是就地排序算法,不需要额外的存储空间。
- 不稳定性:
- 堆排序是不稳定的排序算法,因为相同元素的相对顺序可能会改变。
总结
堆排序是一种高效的排序算法,适合于大规模数据集的排序。它的时间复杂度为O(n log n),并且具有良好的空间效率。然而,堆排序是不稳定的排序算法,且在某些情况下(如数据接近有序时)性能可能不如其他排序算法(如快速排序)。