堆排序(JAVA)
原理:
基本原理也是选择排序,只是不在使用遍历的方式查找无序区间的最大的数,而是通过堆来选择无序区间的最大的数。
注意: 排升序要建大堆;排降序要建小堆。
性能分析:
时间复杂度:O( n * log (n) )
空间复杂度度:O(1)
稳定性:不稳定
实现:
public static void heapSort(int[] arr){
//1.先建立堆
createHeap(arr);
//2.需要循环的取出堆顶元素,和最后一个元素交换位置并删除之
// 再从 0 位置进行调整
int heapSize = arr.length;
for(int i = 0; i < arr.length; i++){
//交换 0 号元素和堆的最后一个元素
swap(arr , 0 , heapSize - 1);
//把最后一个元素从堆上删除
heapSize--;
//从 0 号位置开始往下调整
shiftDown(arr,heapSize,0);
}
}
public static void createHeap(int[] arr){
for(int i = (arr.length - 1 - 1) / 2; i >= 0; i--){
shiftDown(arr,arr.length,i);
}
}
public static void shiftDown(int[] arr,int size, int index){
int parent = index;
int child = 2 * parent + 1;
while(child < size){
//先找出左右子树比较大的
if(child + 1 < size && arr[child + 1] > arr[child]){
child = child + 1;
}
//再去比较 child 和 parent
if(arr[parent] < arr[child]){
swap(arr, parent , child);
}else{
break;
}
parent = child;
child = 2 * parent + 1;
}
}
public static void swap(int[] arr ,int x,int y){
int tmp = arr[x];
arr[x] = arr[y];
arr[y] = tmp;
}
实现main函数:
public static void main(String[] args) {
int[] arr = {1,3,5,7,2,9,6,3};
heapSort(arr);
System.out.println(Arrays.toString(arr));
}