八大排序演算法之選擇排序(SelectionSort)
阿新 • • 發佈:2022-03-02
選擇排序 -- 存在【直接選擇】、【堆排序】
其中兩種選擇演算法都是 不穩定的
點選檢視程式碼
public class SelectionSort { // 核心思想:無序數值中找到最小值,交換到 無序陣列第一位 public void selectSort(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { // 找到最小值 int min = i; for (int j = i + 1; j < arr.length; j++) { if (arr[j] < arr[min]) { min = j; } } if (min != i) { int tmp = arr[i]; arr[i] = arr[min]; arr[min] = tmp; } } } // 堆排序 核心還是建堆 // 將無序陣列建成大頂堆,將最大值(座標 0)和 陣列最後一位 交換,再將剩餘元素重新調整成堆 public void heapSort(int[] arr) { for (int i = (arr.length - 1) / 2; i >= 0; i--) { //從第一個非葉子結點從下至上,從右至左調整結構 heapAdjust(arr, i, arr.length); } //調整堆結構+交換堆頂元素與末尾元素 for (int i = arr.length - 1; i > 0; i--) { //將堆頂元素與末尾元素進行交換 int temp = arr[i]; arr[i] = arr[0]; arr[0] = temp; //重新對堆進行調整 heapAdjust(arr, 0, i); } } /** * 將指定範圍內的陣列調整成大頂堆 * * @param arr * @param parent 需要調整的節點 * @param limit 限定陣列調整的邊界 */ public void heapAdjust(int[] arr, int parent, int limit) { int root = arr[parent]; int lChild = 2 * parent + 1; while (lChild < limit) { // 左右孩子選大值 if (lChild + 1 < limit && arr[lChild + 1] > arr[lChild]) { lChild++; } // 這一塊 arr[lChild] < arr[parent] 是不正確的 需要給 root 找位置 if (arr[lChild] < arr[parent]) { break; } // 將父節點覆蓋 arr[parent] = arr[lChild]; parent = lChild; lChild = 2 * lChild + 1; } arr[parent] = root; } public static void main(String[] args) { SelectionSort selectionSort = new SelectionSort(); int[] arr = new int[]{49, 38, 65, 97, 76, 13, 27}; selectionSort.heapSort(arr); System.out.println(Arrays.toString(arr)); } }