堆排序思想:(以大顶堆为例)
1、先建初始堆,从第一个非叶子节点开始调整堆为一个大顶堆,直到整个待排序列成为一个大顶堆;
2、将堆顶元素与堆中的最后一个元素交换
3、将堆中的最后一个元素移除堆
4、再次调整待排序列为一个大顶堆,从堆中的根节点开始比较,比较该节点的左右子节点,将较大的节点值与根节点的值比较,若根节点的值小于较大子节点,则交换;
5、转到步骤2,直到堆中所有的元素被移除。
堆排序的时间复杂度是:在最坏的情况下仍然是O(NlogN),空间复杂度是O(1),是不稳定的排序;不适合小数据量的排序。
大根堆排序得到的是一个升序排列
小根堆排序得到的是一个降序排列
public static void AdjustHeap(int[] data,int s,int m){//调整堆
int rc = data[s];
for(int j=s*2+1;j<m;j=j*2+1){
if(j+1<m&&data[j]<data[j+1])j++;//如果有右子节点,比较左右子节点的关键字
if(rc>=data[j])break;
data[s]=data[j];
s=j;
}
data[s]=rc; //将堆顶元素放入合适的位置
}
public static void heapsort(int[] data,int n){//堆排序
for(int i=n/2-1; i>=0;i--){//初始化堆
AdjustHeap(data,i,n);
}
for(int i=n-1;i>0;i--){
swap(data,0,i);//将堆顶记录与未排序列中最后一个元素交换
AdjustHeap(data,0,i); //调整堆
}
}
private static void swap(int[] data,int first,int last){
data[first] = data[first] + data[last];
data[last] = data[first] - data[last];
data[first] = data[first] - data[last];
}
public static void main(String[] args){
int[] data = {3,23,22,43,24,63,45,89,12};
heapsort(data,data.length);
for(int i =0;i<data.length;i++){
System.out.println("data["+i+"]"+data[i]);
}
}