1. 堆排序
1.1 算法思想
堆排序是指利用堆这种数据结构所设计的一种排序算法,堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
1.2 算法步骤
- 将初始待排序关键字序列(R1,R2….Rn)构建成大顶堆,此堆为初始的无序区;
- 将最大的数与最低端数交换并排除,此时得到了一个最值数;
- 重复步骤1、2,直至只剩最后一个数。
1.3 复杂度分析
堆排序利用树的思想,只需要logn次遍历就能比较整个堆,因此时间复杂度为O(nlogn),空间复杂度为O(1)。
最好时间复杂度 | 最坏时间复杂度 | 平均时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|---|---|
O(nlogn) | O(nlogn) | O(nlogn) | O(1) | 不稳定 |
2. 代码实现
2.1 Java版
class Solution {
public int[] sortArray(int[] nums) {
// 堆排序
// 交换类排序的升级,
// 时间onlgn,空间o1,不稳定
int[] arr = new int[nums.length];
System.arraycopy(nums,0,arr,0,nums.length);
heapSort(arr);
return arr;
}
private void heapSort(int[] arr){
int len = arr.length;
// 建立堆
for(int i = len / 2 -1; i >= 0; --i){
adjust(arr, len, i);
}
// 调整堆
for(int i = len -1; i > 0;--i){
swap(arr, 0, i);
adjust(arr, i, 0);
}
}
private void adjust(int[] arr, int len, int idx){
int left = 2 * idx+1, right = 2 * idx +2;
int maxIdx = idx;
if(left < len && arr[left] > arr[maxIdx]){
maxIdx = left;
}
if(right < len && arr[right] > arr[maxIdx]){
maxIdx = right;
}
if(maxIdx != idx){
swap(arr, idx, maxIdx);
adjust(arr, len, maxIdx);
}
}
private void swap(int[] arr, int i, int j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}