思路
- 从最后的非叶子节点开始,从后向前构建一个堆(大顶堆/小顶堆);即最后的非叶子节点和其下的叶子节点构成一个大顶堆,然后再找前面一个非叶子节点继续
- 此时根节点是最大的数据,然后将根节点和最后一位进行交换
- 交换后,排除最后一位最大值,再从根节点开始构建大顶堆
- 重复2,3步骤
代码
/**
* 堆排序
*
* @param originArr 需要排序的数组
* @param isMaxHop true:从小到大排序,false:从大到小排序
*/
public static void heapSort(int[] originArr, boolean isMaxHop) {
if (originArr == null || originArr.length == 0) {
return;
}
// 构建堆
createHeap(originArr, isMaxHop);
// 循环2,3步
for (int i = originArr.length - 1; i >= 1; i--) {
// 交换
exchangeElement(originArr, 0, i);
// 重新构建
heap(originArr, 0, i, isMaxHop);
}
}
private static void createHeap(int[] originArr, boolean isMaxHop) {
int half = originArr.length / 2;
for (int i = half; i >= 0; i--) {
heap(originArr, i, originArr.length, isMaxHop);
}
}
private static void heap(int[] originArr, int rootIndex, int length, boolean isMax) {
int leftLeafIndex = rootIndex * 2 + 1;
int rightLeafIndex = rootIndex * 2 + 2;
int index = rootIndex;
if (leftLeafIndex < length && (isMax ? originArr[leftLeafIndex] > originArr[rootIndex] :
originArr[leftLeafIndex] < originArr[rootIndex])) {
index = leftLeafIndex;
}
if (rightLeafIndex < length && (isMax ? originArr[rightLeafIndex] > originArr[index] :
originArr[rightLeafIndex] < originArr[index])) {
index = rightLeafIndex;
}
if (rootIndex != index) {
exchangeElement(originArr, rootIndex, index);
heap(originArr, index, length, isMax);
}
}
private static void exchangeElement(int[] array, int index1, int index2) {
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}