?
堆排序 heapSort
堆是一种数据结构,一种叫做完全二叉树的数据结构。 堆排序是利用堆数据结构而设计的一种排序算法,堆排序是一种选择排序, 其最坏,最好,平均时间复杂度均为O(nlogn),同时也是不稳定排序。
堆的性质
这里我们用到两种堆,其实也算是一种。
大顶堆:每个节点的值都大于或者等于它的左右子节点的值。 对于大顶堆:arr[i] >= arr[2i + 1] && arr[i] >= arr[2i + 2]
小顶堆:每个节点的值都小于或者等于它的左右子节点的值。 对于小顶堆:arr[i] <= arr[2i + 1] && arr[i] <= arr[2i + 2]
堆排序的基本思想是:
- 1、将带排序的序列构造成一个大顶堆,根据大顶堆的性质,当前堆的根节点(堆顶)就是序列中最大的元素;
- 2、将堆顶元素和最后一个元素交换,然后将剩下的节点重新构造成一个大顶堆;
- 3、重复步骤2,如此反复,从第一次构建大顶堆开始,每一次构建,我们都能获得一个序列的最大值,然后把它放到大顶堆的尾部。
- 最后,就得到一个有序的序列了。
public static void main(String[] args) {
int[] arr = new int[]{5, 2, 15, 9, 60, 10, 30, 8, 2, 3, 11};
heapSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void heapSort(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
int len = arr.length;
buildMaxHeap(arr, len);
for (int i = len - 1; i > 0; i--){
swap(arr, i, 0);
len--;
adjust(arr, 0, len);
}
}
private static void buildMaxHeap(int[] arr, int len) {
for (int i = len / 2 - 1; i >= 0; i--) {
adjust(arr, i, len);
}
}
private static void adjust(int[] arr, int i, int len) {
int l = 2 * i + 1;
int r = 2 * i + 2;
int m = i;
if(l < len && arr[l] > arr[m]){
m = l;
}
if(r < len && arr[r] > arr[m]){
m = r;
}
if(m != i){
swap(arr, i, m);
adjust(arr, m, len);
}
}
private static void swap(int[] arr, int x, int y){
arr[x] += arr[y];
arr[y] = arr[x] - arr[y];
arr[x] -= arr[y];
}
public static void main(String[] args) {
int[] arr = new int[]{5, 2, 15, 9, 60, 10, 30, 8, 2, 3, 11};
heapSort(arr);
System.out.println(Arrays.toString(arr));
}
private static void heapSort(int[] arr){
if(arr == null || arr.length <= 0){
return;
}
int len = arr.length;
buildMinHeap(arr, len);
for (int i = len - 1; i > 0; i--){
swap(arr, i, 0);
len--;
adjust(arr, 0, len);
}
}
private static void buildMinHeap(int[] arr, int len){
for (int i = len / 2 - 1; i >= 0; i--) {
adjust(arr, i, len);
}
}
private static void adjust(int[] arr, int i, int len){
int l = 2 * i + 1;
int r = 2 * i + 2;
int m = i;
if(l < len && arr[l] <= arr[m]){
m = l;
}
if(r < len && arr[r] <= arr[m]){
m = r;
}
if(m != i){
swap(arr, m, i);
adjust(arr, m, len);
}
}
private static void swap(int[] arr, int x, int y){
arr[x] += arr[y];
arr[y] = arr[x] - arr[y];
arr[x] -= arr[y];
}
参考: 堆排序
?
|