思路:堆排序用到了二叉树的概念,本文用到了 大根推(上面的数最大,下面2个数小),把数组用二叉树 的形式组合。通过排序,把大的数放到顶部。一次排序后,最大的值放到第一位,将最后一个数跟最大值调换。再次进行排序(不包括最后一个最大值)。循环操作。
代码:
package rank;
public class PileRank { // 堆排序
public static void main(String[] args) {
int[] array = { 4, 2, 5, 1, 7, 3, 8 };
array = pileRank(array);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + "--");
}
}
public static int[] pileRank(int[] array) {
int maxNode = array.length / 2 - 1;// 最大节点数
for (int i = maxNode; i >= 0; i--) {// 第一次先循环,形成一个有序的大顶堆;
pile(array, i, array.length);
}
for (int i = array.length - 1; i > 0; i--) {//
int temp = array[i];// 最大值 放到最后,并不放入循环,重新去最大值
array[i] = array[0];
array[0] = temp;
pile(array, 0, i);
}
return array;
}
// 吧数组按大顶堆排序,第一个数值最大
public static void pile(int[] arr, int parent, int length) {// 数组,父节点下标,数组长度
int parentNodeNumber = arr[parent];// 先取出父节点对应的值,后面有可能要替换
int child = parent * 2 + 1;// 父节点下面的一个左子节点 下标
while (child < length) {
if (child + 1 < length && arr[child + 1] > arr[child]) {// child+1
// 表示右子节点
// <length
// 表示有右节点,比较2节点大小
child++; // 如果右边大 child的自增为右节点的下标
}
if (arr[child] < parentNodeNumber) {// 判断子节点和父节点大小
break;
}
arr[parent] = arr[child];
parent = child;// 继续取下一个子节点 ,原先子节点变为父节点
child = child * 2 + 1;
}
arr[parent] = parentNodeNumber;// 最后把 父节点的值 替换给子节点
}
}