一.堆排序原理
堆排序(Heap Sort)是一种基于堆数据结构的排序算法。堆是一种完全二叉树,其中父节点的值总是大于(或小于)其子节点的值。堆排序的基本思想是先将待排序的数组构建成一个最大堆(或最小堆),然后重复从堆顶取出最大(或最小)元素,放到已排序的部分,再调整剩余元素构建新的堆,直到所有元素都被放置到正确的位置。
堆排序的具体步骤如下:
1.构建最大堆(或最小堆):将待排序的数组看作是一个完全二叉树,并从最后一个非叶子节点开始,自底向上地调整每个节点,使其满足堆的性质。这一步骤保证了最大堆(或最小堆)的构建。
2.取出堆顶元素:将堆顶元素(最大元素或最小元素)与堆中最后一个元素交换位置,并将堆的大小减一。
3.调整堆:将堆顶元素下沉至合适的位置,保持堆的性质。这一步骤重新构建了最大堆(或最小堆)。
4.重复步骤2和步骤3,直到堆为空。
二.使用Java实现堆排序
public class HeapSort { public static void main(String[] args) { int[] arr = {5, 2, 8, 3, 1}; System.out.println("Before sorting:"); printArray(arr); heapSort(arr); System.out.println("After sorting:"); printArray(arr); } public static void heapSort(int[] arr) { int n = arr.length; // 构建最大堆 for (int i = n / 2 - 1; i >= 0; i--) { heapify(arr, n, i); } // 依次取出堆顶元素,进行堆调整 for (int i = n - 1; i >= 0; i--) { // 将堆顶元素与最后一个元素交换 int temp = arr[0]; arr[0] = arr[i]; arr[i] = temp; // 调整堆,保持最大堆性质 heapify(arr, i, 0); } } public static void heapify(int[] arr, int n, int i) { int largest = i; // 当前节点的索引 int leftChild = 2 * i + 1; // 左子节点的索引 int rightChild = 2 * i + 2; // 右子节点的索引 // 如果左子节点大于父节点,更新最大节点的索引 if (leftChild < n && arr[leftChild] > arr[largest]) { largest = leftChild; } // 如果右子节点大于父节点,更新最大节点的索引 if (rightChild < n && arr[rightChild] > arr[largest]) { largest = rightChild; } // 如果最大节点不是当前节点,交换节点的位置并继续调整堆 if (largest != i) { int temp = arr[i]; arr[i] = arr[largest]; arr[largest] = temp; heapify(arr, n, largest); } } public static void printArray(int[] arr) { for (int num : arr) { System.out.print(num + " "); } System.out.println(); } }
以上代码使用堆排序算法对一个整数数组进行排序。heapSort方法实现了堆排序的逻辑,首先构建最大堆,然后重复从堆顶取出最大元素,放到已排序的部分,并调整剩余元素构建新的堆,直到所有元素都被放置到正确的位置。heapify方法用于调整堆,保持最大堆性质。
运行以上代码,将输出如下结果:
Before sorting: 5 2 8 3 1 After sorting: 1 2 3 5 8
堆排序算法的时间复杂度为O(nlogn),其中n是数组的长度。它是一种不稳定的排序算法,适用于任何规模的数组。堆排序在实现上相对较复杂,但由于其在原地排序的特性,对于大规模数据的排序效果较好。