/**
* 先將數組排序成大頂堆(從下到上,從右至左,從第一個非葉子節點開始,數組長度減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);
}
}
堆排序與冒泡排序時間比較截圖: