/**
*实现堆排序[原地堆排序]
*堆适用于动态数据的维护,不适合系统级的排序
*时间复杂度O(nlogn),从小到大排序,前两种堆排序均开辟了额外空间
*不需开辟额外空间,也不需为额外空间进行处理,所以,空间复杂度为O(1)
*根节点从0开始,左孩子:2i+1,右孩子2i+2;
*/
public class HeapSort3 {
public void heapSort3(int[]arr,int n) {
//i=(n-2)/2为第一个不是叶子的节点
//此时即为一个最大堆,arr[0]最大
for(int i=(n-2)/2;i>=0;i--) {
__shiftDown(arr,n,i);
}
//从小到大排序,
for(int i=n-1;i>0;i--) {
swap(arr,0,i);
//交换后数组前面不再是最大堆,对其余i个元素再重新进行堆排序
//只要将第一个元素放在合适的位置即可
__shiftDown(arr,i,0);
}
}
private void __shiftDown(int[] arr, int n, int i) {
//0到n-1个元素
while(2*i+1<n) {
int j=2*i+1;
if(j+1<n&&arr[j+1]>arr[j]) {
j+=1;
}
if(arr[i]>=arr[j])
break;
swap(arr,i,j);
i=j;
}
}
private void swap(int[] arr, int i, int j) {
if(i!=j) {
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
public static void main(String[] args) {
int [] arr= {8,7,4,5,9,2,10,3,3,13,30,3};
int n=arr.length;
HeapSort3 sort3=new HeapSort3();
sort3.heapSort3(arr, n);
for(int i=0;i<n;i++)
System.out.print(arr[i]+" ");
}
}