前端时间树还没整明白呢,所以写排序的时候就没有写堆排序,现在补上
排序原理
1.大顶堆和小顶堆的定义:
大顶堆:每个节点的子节点都小于其父节点
小顶堆:每个节点的子节点都大于其父节点
2.排序思想
以从小到大为例
1)将待排序序列构造成一个大顶堆
2)此时,整个序列的最大值就是堆顶的根节点
3)将其与末尾元素进行交换,此时末尾就为最大值
4)将剩下的n-1个元素重复此操作
3.时间复杂度
堆排序的时间复杂度最好最坏都是O(n*log2n),但是不稳定
4.图解说明
以序列4,6,8,5,9为例
步骤一:得到一个大顶堆
步骤二:将堆顶元素与末尾元素进行交换,使末尾元素最大,然后继续调整堆,再将堆顶元素与末尾元素交换得到第二大元素,重复该步骤
代码:
package two_x_tree;
import java.util.Arrays;
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;
//将无序序列构造成一个大顶堆或小顶堆
//arr.length/2-1表示有多少个叶子节点
for(int i=arr.length/2-1;i>=0;i--){
adjustHeap(arr,i,arr.length);
}
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为非叶子节点得数调整成大顶堆
* @param arr 待调整的数组
* @param i 非叶子节点的索引
* @param length 对length个元素继续调整,length在逐渐减少
*/
public static void adjustHeap(int arr[],int i,int length){
int temp=arr[i];//取出当前元素得值,保存为临时变量
//开始调整
for(int k=i*2+1;k<length;k=k*2+1){
if(k+1<length&&arr[k]<arr[k+1]){
k++;
}
if(arr[k]>temp){
arr[i]=arr[k];
i=k;
}else{
break;
}
}
arr[i]=temp;
}
}