堆排序
堆排序的基本介绍:
堆排序利用堆这种数据结构而设计的一种排序算法,时间复杂度都为O(nlogn),也是不稳定排序。
大顶堆:每个结点的值都不小于孩子结点的值(无左右孩子结点的关系)。
小顶堆:每个结点的值都不大于孩子结点的值
升序排序用大顶堆,降序排序用小顶堆。
基本思想:
- 将待排序序列构造成一个大顶堆
- 此时,整个序列的最大值就是堆顶的根节点。
- 将其与末尾元素进行交换,此时末尾就为最大值。
- 然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。
可以看到在构建大顶堆的过程中,元素的个数逐渐减少,最后就得到一个有序序列了。
代码实现:
package tree;
import java.util.Arrays;
public class HeapSort {
public static void main(String[] args) {
int[] arr = {4,6,8,5,9,-1,99,78,45,88,6,3};
heapsort(arr);
}
//堆排序方法
public static void heapsort(int arr[]){
int temp = 0;
System.out.println("堆排序!!");
//最终代码
//将无序序列构成一个堆
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));
}
//将一个数组(二叉树),调整成大顶堆
public static void adjustHeap(int[] arr,int i,int length){
int temp = arr[i];//先取出当前元素的值,保存在临时变量
//开始调整
//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++;
}
if (arr[k] > temp){ //子结点大于父结点
arr[i] = arr[k];//把较大的值赋给当前结点
i = k;//!!!i指向k,继续循环比较
} else {
break;
}
}
arr[i] = temp;
}
}