目录
一、建堆流程:
1.定义parent游标,数组上从后往前移动(树结构上是从下往上),直到找到有孩子的节点
2.定义child游标,指向parent的左孩子(若有孩子,一定先有左孩子)
3.判断parent有没有右孩子,若有右孩子,左右孩子进行比较,child指向值较大的孩子
4.父子节点进行比较,如果父节点的值大于等于子节点,parent向前移动;否则父子节点的值交换,并且parent指向child,child再指向其左右孩子的最大值,
5,重复4,直到child指向空。或者parent指向的的值大于child
二、代码实现:
1.先写一个check()方法包含parent和child游标,用来检查一个节点是否符合大顶堆
2.定义一个p游标,用for循环在数组上从后往前移动,p指向谁,就用check方法检查谁
//check()方法,检查每个节点是否满足大顶堆,若不满足则把它变成大顶堆
public static void check(int[] arr,int parent,int length) {
//此处的length是数组有效长度
int Maxchild;
int lchild=2*parent+1;
int rchild=2*parent+2;
while(lchild<length) {
if(rchild<length && arr[rchild]>arr[lchild]) {
Maxchild=rchild;
}
else {
Maxchild=lchild;
}
//以上是:若有孩子,则找出左右孩子的最大值
if(arr[Maxchild]>arr[parent]) {
//父节点与最大子节点比较,看是否要交换
int temp=arr[parent];
arr[parent]=arr[Maxchild];
arr[Maxchild]=temp;
//若交换后,父节点指向被交换的child,继续判断
parent=Maxchild;
lchild=2*parent+1;
rchild=2*parent+2;
}
else {break;}
}
}
int[] arr1= {10,5,9,18,6,5,4,8,2,12};
for (int i = arr1.length; i >=0; i--) {
Sorts.check(arr1, i, arr1.length);
}//建堆
System.out.println(Arrays.toString(arr1));//输出一下,检查构建的大顶堆是否成功
三、堆建好后,排序
建完堆之后,再用递归法重复:交换堆上的首尾元素-->重新建堆-->交换首尾元素-->重新建堆.....
//递归法堆排序
public static void heapSort (int[] arr,int length) {
int temp=arr[0];
arr[0]=arr[length-1];
arr[length-1]=temp;
length--;
if(length>0) {
Sorts.check(arr,0,length);
heapSort(arr,length);
}
else {return;}
}
Sorts.heapSort(arr1, arr1.length);//递归法堆排序
System.out.println(Arrays.toString(arr1));
排序结果: