堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆
积的性质:
即子结点的键值或索引总是小于(或者大于)它的父节点。
堆节点的访问:
通常堆是通过一维数组来实现的。在数组起始位置为0的情形中:
·父节点i的左子节点在位置 (2i+1)};
·父节点i的右子节点在位置 (2i+2)} ;
·子节点i的父节点在位置 floor((i-1)/2)} ;
本程序中采用完全二叉树排序(大根树),每一次排序后最大的数据在树根,此时把树顶与树根交换,用树顶来保存数据,即数组从后往前依次保存由大到小的有序数据。堆排序是不稳定的排序,时间复杂度是O(log₂n),空间复杂度是O(1)。
看程序:
import java.util.Arrays;
public class HeapSort {
// 一次二叉树排序
public static void adjust(int[] arr, int start, int end) {
int tmp = arr[start];
for (int i = 2 * start + 1; i <= end; i = 2 * i + 1) {
// 找到子节点中的较大的值
if (i < end && arr[i] < arr[i + 1]) {
i++;
}
// 若子节点的值大于父节点,将子节点的值赋给父结点,同时指针指向该子节点
if (arr[i] > tmp) {
arr[start] = arr[i];
start = i;
// 若子节点的值小于父节点,不做交换
}else {
break;
}
}
arr[start] = tmp;
}
public static void heapSortTest(int[] arr) {
// 第一次调整
for (int i = (arr.length - 1 - 1) / 2; i >= 0; i--) {
adjust(arr, i, arr.length - 1);
}
for (int j = 0; j < arr.length - 1; j++) {
// 交换树顶和树根的值,树根每次前移一位
int tmp = arr[0];
arr[0] = arr[arr.length - 1 - j];
arr[arr.length - 1 - j] = tmp;
// 树根变化后再次调整
adjust(arr, 0, arr.length - 1 - 1 - j);
}
}
public static void main(String[] args) {
int[] arr = {20, 23, 12 , 14, 45, 2, 89, 100, 65, 77, 96};
heapSortTest(arr);
System.out.println(Arrays.toString(arr));
}
}
以上程序的输出结果是:[2, 12, 14, 20, 23, 45, 65, 77, 89, 96, 100]
运行过程: