選擇排序之堆排序(Java)
博客說明
文章所涉及的資料來自互聯網整理和個人總結,意在於個人學習和經驗匯總,如有什么地方侵權,請聯系本人刪除,謝謝!
說明
-
堆排序是利用堆這種數據結構而設計的一種排序算法,堆排序是一種選擇排序,它的最壞,最好,平均時間復雜度均為O(nlogn),它也是不穩定排序。
-
堆是具有以下性質的完全二叉樹:每個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆
大頂堆特點:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
i 對應第幾個節點,i從0開始編號

注意 : 沒有要求結點的左孩子的值和右孩子的值的大小關系。
-
每個結點的值都小於或等於其左右孩子結點的值,稱為小頂堆
小頂堆特點:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]
i 對應第幾個節點,i從0開始編號

一般升序采用大頂堆,降序采用小頂堆
思路
- 將待排序序列構造成一個大頂堆
- 此時,整個序列的最大值就是堆頂的根節點。
- 將其與末尾元素進行交換,此時末尾就為最大值。
- 然后將剩余n-1個元素重新構造成一個堆,這樣會得到n個元素的次小值。如此反復執行,便能得到一個有序序列了。
代碼
package cn.guizimo.tree;
import java.util.Arrays;
/**
* @author guizimo
* @date 2020/8/7 11:43 上午
*/
public class HeapSort {
public static void main(String[] args) {
int max = 8000000;
int[] arr = new int[max];
for (int i = 0; i < max; i++) {
arr[i] = (int)(Math.random() * 8000000);
}
long date1 = System.currentTimeMillis();
heapSort(arr);
long date2 = System.currentTimeMillis();
System.out.println("堆排序"+max+"數組的時間為:"+(date2-date1));
}
public static void heapSort(int arr[]) {
int temp = 0;
for (int i = arr.length / 2 - 1; i >= 0; i--) {
adjustHeap(arr,i,arr.length);
}
//交換
for (int j = arr.length-1;j>0;j--){
temp = arr[j];
arr[j] = arr[0];
arr[0] = temp;
adjustHeap(arr,0,j);
}
//System.out.println(Arrays.toString(arr));
}
//將數組變為大頂推
public static void adjustHeap(int arr[], int i, int length) {
int temp = arr[i];
for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {
if (k + 1 < length && arr[k] < arr[k + 1]) {
k++;
}
if (arr[k] > temp) {
arr[i] = arr[k];
i = k;
} else {
break;
}
}
arr[i] = temp;
}
}
測試

感謝
尚硅谷
萬能的網絡
以及勤勞的自己
關注公眾號: 歸子莫,獲取更多的資料,還有更長的學習計划
