堆排序步骤:
将待排序的数组构造成一个大顶堆(最大值在顶部的堆),取出最大的值,把数组当前最后一个元素换上去,再将数组堆化,这样顶部又是最大的值了,在取出最大值,把数组当前最后一个元素换上去......最终完成排序。
构造大顶堆的方法:
一个个读入数组元素,按照满二叉树的方式一个个插入,当它大于父节点的时候就和父节点换位置,然后再比较换完位置后与当前的父节点的关系,如果还是大于当前父节点再换,直至不在大于父节点。
public class heap_sort {
public static void main(String[] args) {
}
public static void heapSort(int []arr){
if(arr == null || arr.length < 2)
return;
for (int i = 0; i < arr.length; i++) {
heapInsert(arr,i); //把数组整体搞成大根堆(就是说arr[0]目前是最大的值)
}
int heapSize = arr.length;
//把最后一个数和第一个换,这样最大值就去到最后一个了,最大值也就排好了。
swap(arr,0,--heapSize);
while(heapSize>0){
heapify(arr,0,heapSize);
swap(arr,0,--heapSize);
}
}
public static void heapInsert(int[]arr,int index){
// (index-1)/2表示index父节点的index
while(arr[index] > arr[(index - 1) >> 1]){ //如果当前节点比父节点大
swap(arr,index,(index - 1) >> 1); //交换
index = (index - 1) >> 1; //把当前的index换成前父节点的index继续判断
}
}
public static void heapify(int []arr,int index,int heapSize){ //表示从index开始进行堆化
int leftChild = (index << 1) + 1 ; //左孩子等于 index*2+1
while(leftChild < heapSize){ //当左孩子没越界的时候(heapSize所指向的inedx及以后都不是堆的范围内了)
//较大的孩子节点下标为:当右孩子节点存在并且大于左孩子节点时为右孩子下标,否则为左孩子下标
int largeIndex = leftChild+1 < heapSize && arr[leftChild+1] >
arr[leftChild] ? leftChild+1 : leftChild;
//比较孩子节点中较大的那个和父节点谁大,把大的下标赋值给largeindex
largeIndex = arr[index]>arr[largeIndex]?index:largeIndex;
if(largeIndex == index){ //如果大的是父节点自己
break;
}
//如果大的是子节点
swap(arr,largeIndex,index);
index = largeIndex;
leftChild = index*2+1;
}
}
public static void swap(int []arr,int childIndex, int parentIndex){
int a;
a = arr[childIndex];
arr[childIndex] = arr[parentIndex];
arr[parentIndex] = a;
}
}
代码来自左程云。