堆排序
堆排序
堆排序(Heap Sort)是一种树形选择排序,是对直接选择排序的有效改进,利用了堆的性质对要排序的数据进行排序。
堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,如此反复执行,便能得到一个有序序列了。
堆排序的时间复杂度为O(nlogn),空间复杂度为O(1)。
以下是Java代码的演示,实现了一个数组的堆排序。
代码演示:
class Solution {
public int[] sortArray(int[] nums) {
heap_sort(nums, nums.length);
return nums;
}
/*
* 维护大顶堆的性质
* @param nums 存储堆的数组
* @param n 数组的长度
* @param i 被维护节点的下标
*/
public void heapify(int[] nums, int n, int i) {
int largest = i;
int lson = i * 2 + 1;//索引为i的左孩子
int rson = i * 2 + 2;//索引为i的右孩子
if(lson < n && nums[lson] > nums[largest]){
largest = lson;
}
if(rson < n && nums[rson] > nums[largest]){
largest = rson;
}
if(largest != i){
//交换两个元素的值
int temp = nums[largest];
nums[largest] = nums[i];
nums[i] = temp;
heapify(nums, n, largest);
}
}
//堆排序入口
public void heap_sort(int[] nums, int n){
//建堆
for(int i = n/2 - 1; i >= 0; i--){
//自底逐层向上维护
heapify(nums, n, i);
}
//排序
for(int i = n - 1; i > 0; i--){
int temp = nums[0];
nums[0] = nums[i];
nums[i] = temp;
heapify(nums, i, 0);
}
}
}