思路步骤:
1. 建立二叉树结构:
获取需要排序的数组长度,判断要装满所有元素,需要几层(设层数为 n)。
判断条件:2 ^ n - 1 > length;
2. 从下至上,从右至左遍历“二叉树”:
层数减一:n - 1,以去除叶子结点层
从该层最后结点(i = Array[(2 ^ n - 1) - 1])开始,判断是否存在子结点:right = 2 * i + 2;
left = 2 * i + 1;
判断条件:right < length left < length
3. 判断父子结点的大小:
此处以大根堆(大顶堆)为例,若子结点大于父结点,交换二者
判断条件:Array[right] > Array[i] Array[left] > Array[i]
此步可与上一步合成判断,即:right < length && Array[right] > Array[i]
left < length && Array[left] > Array[i]
4. 结点左移:i--,重复 2 ,3 步,终止条件:i < 0
5. 将数组开始与末尾的元素互换,将最大值送去数组尾,剔除数组尾元素,即让其脱离循环:length--
6. 重复 2 ,3 ,4 步,终止条件:length < 0
Java代码如下:
//堆排序
public class heap_sort {
public static void main(String[] args) {
int[] arr = new int[] { 1, 2, 4, 3, 0, -1, -5, 3, 4 };//测试数组
int len = arr.length;// 结点个数
int n = 0;// 二叉树层数
int points;// 记录满二叉树结点数
//找到叶子结点上一层
while (true) {
points = (int) Math.pow(2, n) - 1;
if (points > len) {
n--;// 去除不满的层
break;
}
n++;
}
// System.out.println(n);
points = (int) Math.pow(2, n) - 1;
while (len > 0) {
for (int i = points - 1; i >= 0; i--) {
// System.out.print(arr[i]);
int left = 2 * i + 1;
int right = 2 * i + 2;
//判断有无子树,若有,先判断右结点,再判断左结点
if (right < len && arr[right] > arr[i]) {
int temp = arr[i];
arr[i] = arr[right];
arr[right] = temp;
}
if (left < len && arr[left] > arr[i]) {
int temp = arr[i];
arr[i] = arr[left];
arr[left] = temp;
}
}
System.out.println(Arrays.toString(arr));
int temp = arr[0];
arr[0] = arr[len - 1];
arr[len - 1] = temp;// 将最大值换到数组末尾
System.out.println(Arrays.toString(arr));
len--;
}
}
}