假设数组 arr[]= {5,7,4,2,0,3,1,6},请通过插入排序的方式,实现从小到大排列:
方法:①利用完全二叉树构建大顶堆;
②对顶元素和堆底元素进行交换,除堆底元素之外其余元素继续构造大顶堆;
③重复步骤②,直到所有元素都不参与构建,整个数组排序完成
【完全二叉树--数据从上到下,从左到右排列】
【大顶堆--父结点的值大于或等于左右孩子结点的值】
堆顶元素和堆底元素进行交换(注:每次交换取值后都要剩余部分重新构建大顶堆)
【大顶堆的检验和调整】
1.定义parent游标指向检测的节点
2.定义parent的左孩子child(有孩子就一定会有左孩子)
3.判断有没有右孩子,如果有右孩子,左右孩子进行比较,让child指向左右孩子中的最大值。
4.parent和child指向的值进行比较,若parent值更大,则符合大顶堆;若parent的值更小,则父子节点进行交换,parent指向child,child指向其左右孩子中的最大值,继续进行比较,直到child为空或是parent指向值最大,则停止。
package Java.start;
import java.util.Arrays;
public class HeapSort {
//堆排序
public static void main(String[] args) {
int[] arr= {5,7,4,2,0,3,1,6};
//一、构建大顶堆
for (int p=arr.length-1;p>=0;p--) {
adjust(arr, p, arr.length);
}
//二、堆底堆顶元素进行交换
for(int i=arr.length-1;i>0;i--) {
int temp=arr[i];
arr[i]=arr[0];
arr[0]=temp;
adjust(arr, 0, i);
}
//打印
System.out.println(Arrays.toString(arr));
}
//堆的维护
public static void adjust(int[] arr,int parent,int length) {
//定义左孩子
int child=2*parent+1;
while(child<length) {
//定义右孩子
int rchild=child+1;
if(rchild<length && arr[rchild]>arr[child]) {
child++;
}
//child指向左右孩子中的最大值
//父子节点进行比较
if(arr[parent]<arr[child]) {
//父子节点进行交换
int temp=arr[parent];
arr[parent]=arr[child];
arr[child]=temp;
//parent指向child,child继续指向左右孩子中的最大值
parent=child;
child=2*child+1;
}else {
break;
}
}
}
}
结果: