堆排序是一种基于堆数据结构的排序算法。它通过将待排序的元素构建成一个二叉堆,然后逐步将最大(或最小)元素从堆中取出来放到已排好序的数组中,直至所有元素都被排序完毕。
Java代码示例:
public class HeapSort {
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--) {
swap(arr, 0, i);
heapify(arr, i, 0);
}
}
private static void heapify(int[] arr, int n, int i) {
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left] > arr[largest]) {
largest = left;
}
if (right < n && arr[right] > arr[largest]) {
largest = right;
}
if (largest != i) {
swap(arr, i, largest);
heapify(arr, n, largest);
}
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
时间复杂度分析:
堆排序的时间复杂度为O(nlogn),其中n为待排序元素个数。构建最大堆的时间复杂度为O(n),依次取出堆顶元素并调整堆的时间复杂度为O(logn),共需要执行n-1次,因此总时间复杂度为O(nlogn)。
空间复杂度分析:
堆排序的空间复杂度为O(1),只需要常数级别的额外空间来记录交换和比较操作。
优劣势分析:
堆排序的主要优点是不会因为输入数据的变化而导致性能下降,因此适合于大规模数据的排序。同时它的时间复杂度也比较稳定,最好、平均、最差情况下都是O(nlogn)。缺点是其常数项较大,不如快速排序等算法在小规模数据上表现优秀。
使用示例:
public class Main {
public static void main(String[] args) {
int[] arr = { 5, 3, 8, 6, 2, 7, 1, 4 };
HeapSort.heapSort(arr);
System.out.println(Arrays.toString(arr));
}
}
输出结果为:[1, 2, 3, 4, 5, 6, 7, 8]
总结:
堆排序是一种基于堆数据结构的排序算法,具有时间复杂度稳定、适合大规模数据排序的优点。其主要缺点是常数项较大,不如快速排序等算法在小规模数据上表现优秀。堆排序的时间复杂度为O(nlogn),空间复杂度为O(1)。