学习自严蔚敏、吴伟民的《数据结构》-清华大学出版
过于复杂,理解的不够透彻,只存放代码部分
1、建立堆:
/**
* 由于使得数组元素递增排序,所以先建一个“大顶堆”,即先选得一个关键字为最大的记录并与序列中最后一个记录交换
* 所以,每次访问数组会是n-i
* @param arr-数组元素
* @param s-开始位置-0
* @param m-结束位置-逐渐减1(从数组长度开始)
*/
public static void heapAdjust(int[] arr, int s, int m) {
// 已知arr[s~m]中的元素除arr[s]之外均满足堆的定义,本函数调整arr[s]的元素,使arr[s~m]成为一个大顶堆(对其中元素而言)
int rc = arr[s];
// 相当于二叉树,当前结点的下一层
for (int j = 2 * s; j < m; j *= 2) {
// 选出较大的结点
if (j < m && arr[j] < arr[j + 1]) {
++j;
}
// 若比第一个结点(根结点)小,则结束本次循环
if (!(rc < arr[j])) {
break;
}
// 说明比根结点大,将至向前移动
arr[s] = arr[j];
// 记录当前空出的结点位置
s = j;
}
// 将空出结点的位置存放之前的根结点
arr[s] = rc;
}
2、通过上述方法将数组排序(递增)
public static void heapSort(int[] arr) {
// 将最大数移到首位,并且是符合堆的定义
// 把无序数组建成大顶堆:从【arr.length / 2】开始向前遍历,结束后便得到大顶堆
for (int i = arr.length / 2; i >= 0; i--) {
heapAdjust(arr, i, arr.length);
}
for (int i = arr.length - 1; i > 0; i--) {
// 将堆顶元素(当前最大元素)和当前未经排序子序列arr[0~i]中最后一个记录交换
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
// 将arr[0~i]重新调整为大顶堆
heapAdjust(arr, 0, i - 1);
}
}