//堆排序
public static void heapSort(int[]arr){
if (arr.length<2){
return;
}
for (int i = 0; i < arr.length; i++) {//将数组构造成一个堆
heapInsert(arr,i);
}
//经过创建堆之后现在最大的元素在数组的第一个位置,将第一个元素依次与 堆 最后一个元素交换
int heapEndIndex=arr.length;//记录堆的结束位置
while (heapEndIndex>0){
swap(arr,0,--heapEndIndex);
heapify(arr,0,heapEndIndex);//将第一个元素与堆最后一个元素交换后堆的特性就破坏了,需要进行堆调整
}
}
//堆插入(创建堆的过程)
//将数组想象成一个堆,从数组第一个元素开始将后边的元素依次插入创建好的堆中
private static void heapInsert(int[]arr,int index){
while (arr[index]>arr[(index-1)/2]){//创建最大堆,数组下标为index在堆中父节点在数组中的下标为:(index+1)/2
swap(arr,index,(index-1)/2);
index=(index-1)/2;
}
}
//堆调整
//将当前位置的数依次和左右子节点中较大的进行交换
private static void heapify(int[]arr,int index,int heapEndIndex){
int left=2*index+1;
while (left<heapEndIndex){
int right=left+1;
int maxLocal;//左右子节点较大的位置
if (right>=heapEndIndex){//如果右子树超出了堆结束的位置则不交换,以为堆结束位置之后已经是排序好的数组
maxLocal=left;
}else {
maxLocal=arr[left]>arr[right]?left:right;
}
if (arr[maxLocal] <= arr[index]) {
break;
}
swap(arr,index,maxLocal);
index=maxLocal;
left=2*index+1;
}
}