一、堆排序简介
堆排序基本介绍
1)堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为0(nlogn),它也是不稳定排序。
2)堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆,注意:没有要求结点的左孩子的值和右孩子的值的大小关系。
3)每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆
堆排序的基本思想:
1)将待排序序列构造成一个大顶堆
2)此时, 整个序列的最大值就是堆顶的根节点。
3)将其与末尾元素进行交换,此时末尾就为最大值。
4)然后将剩余n-1个元素重新构造成一个堆, 这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。在构建大顶堆的过程中,元素的个数逐渐减少,最后就得到一个有序序列了.
二、代码实现
package sort;
import java.util.Arrays;
public class HeapSort {
public static void main(String[] args){
int[] arr={8,2,6,3,9,5,1};
heapSort(arr);
}
//定义堆排序的方法
public static void heapSort(int[] arr){
//定义临时变量,用于大顶堆排序时的交换
int temp =0;
System.out.println("待排序数组:"+Arrays.toString(arr));
//分步完成
/*
adjustHeap(arr,1,arr.length);
System.out.println("第一次:"+ Arrays.toString(arr));
adjustHeap(arr,2,arr.length);
System.out.println("第二次:"+ Arrays.toString(arr));
adjustHeap(arr,0,arr.length);
System.out.println("第三次:"+ Arrays.toString(arr));
*/
//循环完成排序
for (int i = arr.length/2-1;i>=0;i--){
adjustHeap(arr,i,arr.length);
System.out.println("调整大顶堆过程中...:"+ Arrays.toString(arr));
}
System.out.println("此时已经将数组调整为大顶堆!!!");
for (int j=arr.length-1;j>0;j--){
temp =arr[j];
arr[j] =arr[0];
arr[0] =temp;
adjustHeap(arr,0,j);//每交换一次,再次调整为大顶堆,只不过下次无序
}
System.out.println("堆排序完成~~"+Arrays.toString(arr));
}
//定义一个方法,用于将顺序存储的数组(二叉树),调整为一个大顶堆
//arr:传进来的无序数组、i:数组中对应非叶子节点的下标、length:没调整一次会变化
public static void adjustHeap(int[] arr,int i,int length){
//定义一个临时变量temp,存放当前非叶子节点arr[i]的值
int temp =arr[i];
for (int k =2*i+1;k<length;k=2*k+1){
if (arr[k] < arr[k+1] && k+1 < length){//右子节点大于左子节点
k++;//k指向右子节点
}
if(arr[k]>temp){//子节点大于父节点
arr[i]=arr[k];
i=k;
}else{
break;
}
}
//循环目的是为了寻找最大值放在i为父节点的树的最大值,所以循环结束后,已经将索引为i的父节点的最大值放在了该树的顶部(局部)
arr[i]=temp;
}
}
结果截图