排序算法(一):java实现堆排序
堆排序的基本思想
堆排序就是利用堆(假设进行升序,也就是使用大顶堆)进行排序的方法。它的基本思想是,将待排序的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根结点。将其与堆数组的末尾元素交换,此时末尾元素就是最大值,然后将剩余的 n - 1 个序列重新构造成一个堆,这样就得到 n - 1个元素中的次大值。如此反复执行, 便能得到一个有序序列了 。
这里构造大顶堆的时候是从最后一个节点的父节点开始的,也就是arr.length/2-1,从下至上,从右至左依次调整,调整完后堆顶为最大值,再与最后一个元素交换,交换完后再调整。
调整时是从该节点的左右孩子进行比较,孩子节点为K=2*i+1,左孩子大就取左右孩子大则K+1,根节点大则break;这里交换用了个位运算可以简单装一下,代码如下:
public class HeapSort {
public static void main(String[] args) {
int arr[]={19, 8, 27, 6, 315, 14, 99};
HeapSort heap=new HeapSort();
heap.heapSort(arr);
System.out.println(Arrays.toString(arr));
}
private void heapSort(int[] arr) {
//先构建大根堆 从最后节点的父节点开始,下至上,右至左
for(int i=arr.length/2-1;i>=0;i--){
adjustHeap(arr,i,arr.length);
}
//将堆顶元素与最后一个元素交换,再继续调整堆
for(int j=arr.length-1;j>0;j--){
swap(arr,0,j);
adjustHeap(arr, 0, j);
}
}
private void swap(int[] arr, int i, int j) {
arr[i]=arr[i]^arr[j];
arr[j]=arr[i]^arr[j];
arr[i]=arr[i]^arr[j];
}
private void adjustHeap(int[] arr, int i, int length) {
int temp=arr[i];
//k为初始化节点i的左孩子节点
for(int k=2*i+1;k<length;k=k*2+1){
if(k+1<length&&arr[k]<arr[k+1]){ //左孩子<右孩子,则取右孩子
k++;
}
if(temp>=arr[k]){
break;
}else{ //根节点<左右孩子结点,则交换
arr[i]=arr[k];
i=k;
}
}
arr[i]=temp;
}
}
时间复杂度: