堆排序:
堆排序的数据结构是完全二叉树,需要转换为大顶堆,即每个节点的值都大于或者等于它的左右子节点的值,小顶堆则反之。
思路:
- 从尾部到首部进行遍历。
- 将第0个节点到第i个节点进行大顶堆构建。
- 不断的比较第i个节点的父节点与子节点,若父节点大于子节点则进行交换。
- 进行i–操作继续交换,直到完成大顶堆构建。
- 每完成一次大顶堆构建,就将第0个元素与第i个元素进行交换。
public class HeapSort {
public static void main(String[] args) {
int[] arr = {7, 4, 1, 3, 2, 9, 5, 8};
sort(arr);
System.out.println(Arrays.toString(arr));
}
static void sort(int[] arr) {
// 若第0个节点大于第i个节点,则进行交换
for (int i = arr.length - 1; i > 0; i--) {
// 从第0个节点到第i个节点大顶堆化
maxHeap(arr, i);
swap(arr, 0, i);
}
}
/**
* 进行大顶堆构建
* @param arr
* @param i
*/
static void maxHeap(int[] arr, int i) {
// 定义子节点
int child = 0;
// 从i节点的父节点倒序遍历
for (int parent = (i - 1) / 2; parent >= 0; parent--) {
// 根据父节点计算左节点
child = parent * 2 + 1;
// 若为右节点,且右节点大于左节点(若左节点 != i && 左节点 < 右节点)
if (child != i && arr[child] < arr[child + 1]) {
child ++;
}
// 找出子节点较大的元素,若大于父节点则进行交换
if (arr[parent] < arr[child]) {
swap(arr, parent, child);
}
}
}
static void swap(int[] arr, int parent, int child) {
int temp = arr[parent];
arr[parent] = arr[child];
arr[child] = temp;
}
}