private void heapSort(Integer[] objArr) {
// 堆结构中 左子节点的 leftSonIndex = 2 * parentIndex + 1
// 右子节点的 rightSonIndex = 2 * parentIndex + 2;
// parentIndex = sonIndex / 2;
//https://zhuanlan.zhihu.com/p/265493303
//https://www.cnblogs.com/chengxiao/p/6129630.html
for (int i = objArr.length / 2 - 1 ; i >= 0 ; i --){
adjustHeap(objArr , i , objArr.length);
}
for ( int i = objArr.length ; i > 0 ; ){
if(i == 1){
break;
}
swap(objArr , 0 , i - 1);
adjustHeap(objArr , 0 , --i);
}
}
private void adjustHeap(Integer[] objArr , int parentIndex , int length){
// 进入循环说明 parentIndex 存在左子节点
for (int i = 2 * parentIndex + 1 ; i < length ; ) {
int largestIndex = parentIndex;
//如果小于左子节点 最大值的索引就是 左子节点的索引值
if(objArr[largestIndex] < objArr[i]){
largestIndex = i;
}
//如果存在右子节点 且 左子节点大于右子节点
if(i + 1 < length && objArr[largestIndex] < objArr[i + 1]){
largestIndex = i + 1;
}
// 如果父节点不是最大的节点
if(parentIndex != largestIndex){
// 父节点与最大的子节点交换
swap(objArr , parentIndex , largestIndex);
// 交换以后 largestIndex 索引处放的是之前的父节点的值
// 这样就有可能导致 largestIndex 这个节点以及它的子树不再是大根堆
// 计算出 largestIndex 理论上的左子节点的索引 用来判断其有没有左子节点
// 如果计算出来的左子节点索引小于 length 说明存在左子节点
i = 2 * largestIndex + 1;
parentIndex = largestIndex;
}else {
// 如果父节点就是最大节点 不需要继续调整其子树了
break;
}
}
}
堆排序 java 实现
最新推荐文章于 2024-05-18 16:42:38 发布