堆排序
基本介绍
- 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏 ,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序
- 堆是具有以下性质的完全二叉树:每个节点的值都大于或等于其左右孩子节点的值,称为大顶堆,注意没有要求节点的左孩子的值和右孩子的值的大小相等
- 每个节点的值都小于或等于其左右孩子节点的值,称为小顶堆
4.一般升序采用大顶堆,降序采用小顶堆
基本思想
…建堆,交换…建堆,交换…建堆,交换…建堆,交换…
- 将待排序序列构成一个大顶堆
- 此时,整个序列的最大值就是堆顶的根节点
- 将其与末尾元素交换,此时末尾就成为最大值
- 然后将剩余n-1个元素重新构造成一个堆。这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列
可以看到在构建大顶堆的过程中,元素的个数逐渐减少,最后得到一个有序序列
思路分析
以 int[] arr = {4,6,8,5,9};数组堆排序的分析过程为例
代码
package J树的提高;
import sun.misc.LRUCache;
import java.util.Arrays;
/**
* @Author Zhou jian
* @Date 2020 ${month} 2020/1/9 0009 13:57
* 堆排序
*/
public class HeapSort {
public static void main(String[] args) {
//要求将数组升序排列
int[] arr = {4,6,8,5,9};
heapSort(arr);
}
//编写一个堆排序的方法
public static void heapSort(int[] arr){
int temp = 0;
System.out.println("堆排序");
//分步完成
// adjustHeap(arr,1,arr.length);
// System.out.println("第一次"+ Arrays.toString(arr));//4 9 8 5 6
//
// adjustHeap(arr,0,arr.length); //9 6 8 5 4
// System.out.println("第而次"+ Arrays.toString(arr));//9 6 8 5 4
//完成最终代码
//将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆
for(int i=arr.length/2-1;i>=0;i--){
adjustHeap(arr,i,arr.length);
}
// System.out.println(Arrays.toString(arr));
//将堆顶元素与末尾元素交换,将最大元素 “沉”到数组末端
//重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序
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));
}
//将一个数组(二叉树)调整成一个大顶堆
/**
* 功能:完成将以i指向对应的非叶子节点对应的树调整成大顶堆
* 举例:int[] arr = {4,6,8,5,9} ;=> i=1=>adjustHeap =>得到{4,9,8,5,6}
* 再次调用adjustHeap传入的i=0=> 得到{4,9,8,5,6}=>{9,6,8,5,4}
* @param arr 待调整的数组
* @param i 表示非叶子结点在数组中的索引
* @param length 表示对多少个元素进行调整,length在逐渐减少
*/
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++; //k指向右子节点
}
if(arr[k]>temp){//如果子节点大于父节点
arr[i]=arr[k]; //把较大的值赋给当前节点
i=k;//让i指向k,继续循环比较
}else{
break; //从左到右从下到上调整
}
}
//当for循环结束后,我们已经将i为父节点的树最大值,放在了最顶(局部)
arr[i]=temp;//将temp值放到调整后的位置
}
}