堆排序
小根堆,和大根堆都是一棵完全数(除了最后一排都是满的,最后一排的叶子节点从最左段开始插入)
小根堆,每个节点都比它的左右子树的节点要小
大根堆,每个节点都比它的左右子树的节点要大
过程
- 先构建一个小(大)根堆,每次新建的节点都要和父节点比较,要比父节点小,交换位置,直到比较到根节点,
- 构建完成后再取根节点,再把整个堆的最后一个结点放到根节点的位置,调整整个堆为小(大)顶堆,
- 再取根节点,。。。最后形成一个有序数组,
== 小顶堆构建一个升序序列 大顶堆构建一个降序序列==
package com.qcby.bilbil.sort;
import java.util.Arrays;
/**
* @author HuangHaiyang
* @description: description
* @version: 1.0.0
*/
public class Heap {
public static void main(String[] args) {
int[] nums = new int[]{53, 56, 24, 86, 45, 41, 78, 12, 10, 50, 31, 42, 16, 25, 3, 85, 49};
sort(nums);
System.out.println(Arrays.toString(nums));
}
public static void sort(int[] nums) {
int temp=0;
for (int i = nums.length/2-1; i >=0 ; i--) {
adjust(nums,i,nums.length);
}
for (int i = nums.length-1; i >0 ; i--) {
temp=nums[i];
nums[i]=nums[0];
nums[0]=temp;
adjust(nums,0,i);
}
}
/**
* @param nums 传入的数组
* @param index 调整的结点的下标
* @param length 长度
* @return: void
*/
public static void adjust(int[] nums, int index, int length) {
int temp = nums[index];
//i = index*2+1 找到这个节点的左子树
for (int i = index * 2 + 1; i < length; i = i * 2 + 1) {
if (i + 1 < length && nums[i] < nums[i + 1]) {
i++;//如果右节点每越界,并且左节点的值小于右节点的值,让i指向右节点
}
//找到 左右子树中较大的那个值,如果它比temp大 需要调整
if(nums[i]>temp){
nums[index]=nums[i];
index=i;
}else {
break;
}
}
nums[index]=temp;
}
}