/**
* 先将数组排序成大顶堆(从下到上,从右至左,从第一个非叶子节点开始,数组长度减1再除以2作为父节点,
* 先将左节点与右节点比较,再将大的一个子节点与父节点比较,也就是选取最大的作为父节点)
* 将数组末尾与数组开始(array[0])交换(既数组最大值在末尾,数组长度减1)
* 重调数组成大顶堆(数组起始值与子节点比较,将大的字节点复值给父节点,再将大的字节点作为父节点与其字节点比较,
* 重复前面操作,直至超出数组长度,就跳出循环,再将数组的初始值赋值给最后一个父节点。相当于填坑操作)
* 再进行交换操作(数组长度-1),重复直至长度为1。
*/
public class Sort {
private static void adjustHeap(int[] arr, int parent, int length) {
//temp存储父节点的值
int temp = arr[parent];
//左子节点
int lChild = 2 * parent + 1;
while (lChild < length) {
//右子节点
int rChild = lChild + 1;
// 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点
if (rChild < length && arr[lChild] < arr[rChild]) {
lChild++;
}
// 如果父结点的值已经大于孩子结点的值,则直接结束
if (temp >= arr[lChild]) {
break;
}
// 把孩子结点(大值)的值赋给父结点
arr[parent] = arr[lChild];
//选取孩子结点(大值),继续向下筛选(重新调整时才会用到,初次排序会跳出循环)
parent = lChild;
lChild = 2 * lChild + 1;
}
//填坑最后一步
arr[parent] = temp;
}
//堆排序
public static void heapSort(int[] arr) {
long startTime=System.nanoTime();
//创建堆
for (int i = (arr.length - 1) / 2; i >= 0; i--) {
//从第一个非叶子结点从下至上,从右至左调整结构
adjustHeap(arr, i, arr.length);
}
//调整堆结构+交换堆顶元素与末尾元素
for (int i = arr.length - 1; i > 0; i--) {
//将堆顶元素与末尾元素进行交换
int temp = arr[i];
arr[i] = arr[0];
arr[0] = temp;
//重新对堆进行调整
adjustHeap(arr, 0, i);
}
long endTime=System.nanoTime();
System.out.println(endTime-startTime);
}
//冒泡排序
public static void bubbleSort(int[] array) {
long startTime = System.nanoTime();
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length - 1 - i; j++)
if (array[j + 1] < array[j]) {
int temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
}
long endTime = System.nanoTime();
System.out.println(endTime - startTime);
}
}
堆排序与冒泡排序时间比较截图: