堆排序
思想:1、将无序序列构建成一个堆,根据升序降序需求选择大顶堆或者小顶堆;
2、将堆顶元素与末尾元素交换,将最大元素“沉”到数组末端;
3、重新调整结构 ,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
import java.util.Arrays;
public class HeapSort {
/*
* 堆排序
*/
public static void sort (int[] arr) {
//构建大顶堆
for (int i = arr.length / 2 - 1; i >= 0; i--) {
//从非叶子叶子节点开始从下至上,从左至右调整结构
adjustHeap(arr, i, arr.length);
}
//调整堆结构+交换堆顶元素与末尾元素
for (int j = arr.length - 1; j > 0; j--) {
//将堆顶元素与末尾元素进行交换
swap(arr, 0, j);
//重新对堆进行调整
adjustHeap(arr, 0, j);
}
}
//调整大顶堆(仅是调整过程,建立在大顶堆已构建的基础上)
public static void adjustHeap (int[] arr, int i,int length) {
int left, right, j;
//判断当前父节点有无左节点(即有无孩子节点,left为左节点)
while ((left = 2 * i + 1) < length ) {
//右节点
right = left + 1;
//j指针指向左节点
j = left;
//右节点大于左节点
if (right < length && arr[left] < arr[right]) {
//当前指针指向右节点
j++;
}
//将父节点与孩子节点交换
if (arr[i] < arr[j]) {
swap(arr, i, j);
}
//i = j是针对在父节点和子节点进行调整后仍需要对子节点和孙子节点进行调整
i = j;
}
}
//交换元素
public static void swap(int[] arr,int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
public static void main(String[] args) {
int[] arr = {20, 50, 20, 40, 70, 10, 80, 30, 60};
sort(arr);
System.out.println(Arrays.toString(arr));
}
}