堆排序首先要建堆(大堆、小堆,这里以大堆为例)
从下往上调整:(从第一个非叶结点开始)
每次建好堆后,堆顶元素与堆尾元素交换位置,再对除堆尾元素后剩下的元素进行调整,重新建堆
新建的堆(除去上一次的堆尾)中,堆顶与堆尾元素交换位置,除去堆尾元素进行调整……直到调整到堆顶位置处
/**
* 堆排序
* 要注意的点:建堆、除去堆顶元素后剩余元素如何调整
*/
public int[] heapSort(int[] arr){
int len = arr.length - 1;
//建堆
for(int i=len/2-1; i>=0; i--){
heapAdjust(arr,i,len);
}
while(len >= 0){
swap(arr, 0 , len--);//根结点与“尾节点”交换
heapAdjust(arr,0,len);//除了尾节点以外的结点,重新调整成堆
}
return arr;
}
public void heapAdjust(int[] arr, int i, int len){
int left,right,j;
while((left=2*i+1) <= len){//当前父结点有左孩子
right = left + 1;
j = left;
if(j<len && arr[left]<arr[right]){//右孩子>左孩子
j++;//j指向右孩子
}
if(arr[i] < arr[j]){//父与大的孩子交换
swap(arr,i,j);
}else{
break;
}
i = j;
}
}