你好呀!我是陌陌
1. 堆概述
堆,逻辑上是个二叉树,而物理上我们可以使用数组来实现堆
2. 堆排序实现
2.1 基本思路
- 首先俺们手中拿上了一个待排序的数组,设置一个参数heapSize
- 先将其转换为大根堆(我们就很容易的得到这个数组中的最大值,就是arr[0])
- 下面提供的代码中heapify()和heapInsert()方法都是可以将数组转换为大根堆的~
- 将这个我们得到的最大值和堆中最后一个数进行交换,heapSize–
- 循环2、3直至heapSize == 0
- 这样我们就得到了一个有序的数组啦~
2.2 代码实现
public class Test2 {
public static void main(String[] args) {
int[] a = {2,5,1,5,7,3,5,2};
heapSort(a);
System.out.println(Arrays.toString(a));
}
//堆排序
public static void heapSort(int[] arr){
if(arr == null || arr.length < 2){
return;
}
//下面两个循环的目的都是要将堆调整为大根堆
//二者不同的是:
// 第一个循环是以树根开始向上不断的进行转换
// 第二个循环是以树叶开始向上的不断进行转换
// for(int i = 0;i < arr.length;i++){
// heapInsert(arr,i);
// }
for (int i = arr.length - 1; i >= 0; i--) {
heapify(arr,i,arr.length);
}
int heapSize = arr.length;
swap(arr,0,--heapSize);
while(heapSize > 0){
heapify(arr,0,heapSize);
swap(arr,0,--heapSize);
}
}
//将堆中index ~ heapSize之间的结构调整为大根堆
public static void heapify(int[] arr,int index,int heapSize){
int left = index * 2 + 1;
while(left < heapSize){
int largest = left + 1 < heapSize && arr[left +1] > arr[left]? left +1:left;
largest = arr[largest] > arr[index]?largest:index;
if(largest == index){
break;
}
swap(arr,largest,index);
index = largest;
left = index * 2 + 1;
}
}
//将堆调整为大根堆
public static void heapInsert(int[] arr,int index){
while(arr[index] > arr[(index - 1)/2]){
swap(arr,index,(index - 1)/2);
index = (index - 1)/2 ;
}
}
//交换数组中i和j位置的两个数据
public static void swap(int[] arr,int i,int j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
2.3 时间复杂度
O(NlogN)
请不要问俺为什么,我也不知道为什么,呜呜呜,希望有大神来解答一下
3. 参考
想要详细了解的友友,可以看暴躁左神的课👇
告辞~