堆排序
大根堆:所有父节点的值大于等于子节点的值
小根堆:所有父节点的值小于邓等于子节点的值
堆排序基本思想:
1.将待排序列构造成一个大根堆
2.此时整个序列的最大值就是堆顶的跟结点
3.将其与末尾元素进行交换,此时末尾就是最大值
4然后 将剩余n-1个元素重新构造一个值,反复循环即可。
/*
*
*
* i表示叶子结点在数组中索引
* length 表示对多少个元素继续调整,length是在逐步的减少
*
* */
public class Day09022 {
public static void main(String[] args) {
Day09022 day09022 = new Day09022();
int [] arr={4,6,8,5,9,-1,96,99};
ad(arr);
System.out.println(Arrays.toString(arr));
}
public static void ad(int [] arr){
//完成我们最终代码
//1.将无序序列构建成一个堆,根据升序降序需求选择大根堆或者小根堆
for(int i=arr.length/2-1;i>=0;i--){
adjustHeap(arr,i,arr.length);
}
//2.将堆顶元素与末尾元素进行交换,此时末尾就是最大值
//3.然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次最小值,如此反复执行,便能得到一个有序序列了
for(int j=arr.length-1;j>0;j--){
int temp =arr[j];
arr[j]=arr[0];
arr[0]=temp;
adjustHeap(arr,0,j);
}
}
public static void adjustHeap(int arr[], int i, int length) {
int temp = arr[i];//先取出当前元素的值,保存临时变量
//1.k=i*2+1 k是i的左子节点
for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {
if (k + 1 < length && arr[k] < arr[k + 1]) {//说明左子结点的值小于右子节点的值
k++;// }
}
if(arr[k]>temp){//如果子节点大于父节点
arr[i]=arr[k];//把较大的值赋给当前结点
i=k;//i 指向k 继续向下进行比较
}else{
break;
}
}
//当for循环结束后,我们已经将以i为父节点的树的最大值,放在了最顶(局部)
arr[i]=temp;
}
}