演算法-堆排序
阿新 • • 發佈:2021-08-04
堆排序
- 先讓整個陣列都變成大根堆結構,建立堆的過程
- 從上到下的方法,時間複雜度為O(logN*N)
- 從下到上的方法,時間複雜度為O(N)
- 把堆的最大值和堆末尾的值進行交換,然後減少堆的大小之後,再去調整堆,一直周而復始,時間複雜度為O(N)
- 堆的大小減成0之後,排序完成
圖示
程式碼
其實你會將資料調整為 小根堆或者大根堆,你就會堆排序了
從上到下構建堆
/** * * 從上之下 * @param heap * @param index */ public void heapInsert(int[] heap, int index) { // 父節點(index - 1) / 2小於當前節點 while (heap[(index - 1) / 2] < heap[index]) { // 交換 swap(heap,(index - 1) / 2,index); index = (index - 1) / 2; } }
從下到上構建堆
private void heapfiy(int[] arr, int index, int heapSize) { // 獲取當前index 的左孩子 int left = index * 2 + 1; // 左孩子節點小於堆大小 while (left < heapSize) { // 孩子節點的最大 值的位置值 int lagest = left + 1 < heapSize && arr[left + 1] > arr[left] ? left + 1 : left; // 判斷index 和孩子節點的值大小 lagest = arr[index] > arr[lagest] ? index : lagest; // 如果當前節點就是最大的不需要繼續下沉,跳出 if (lagest == index) { break; } // 交換 swap(arr, index, lagest); index = lagest; // 獲取最大的節點的左孩子節點 left = index * 2 + 1; } }
整個堆排序程式碼
public class HeapSort { private void heapfiy(int[] arr, int index, int heapSize) { // 獲取當前index 的左孩子 int left = index * 2 + 1; // 左孩子節點小於堆大小 while (left < heapSize) { // 孩子節點的最大 值的位置值 int lagest = left + 1 < heapSize && arr[left + 1] > arr[left] ? left + 1 : left; // 判斷index 和孩子節點的值大小 lagest = arr[index] > arr[lagest] ? index : lagest; // 如果當前節點就是最大的不需要繼續下沉,跳出 if (lagest == index) { break; } // 交換 swap(arr, index, lagest); index = lagest; // 獲取最大的節點的左孩子節點 left = index * 2 + 1; } } /** * 陣列兩個位置交換 * @param arr * @param i * @param j */ private void swap(int[] arr, int i, int j) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } @Test public void testHeapSort() { int[] arr = {1, 20,18, 6, 9, 2, 10, 11, 7}; // 構建最大根堆 for (int i = 0; i < arr.length; i++) { heapfiy(arr, arr.length - 1 - i, arr.length); } System.out.println("----------------------"); for (int i : arr) { System.out.print (i+" "); } System.out.println(); System.out.println("----------------------"); /* * 最大跟交換 * heapSize -- * heapFiy呼叫 */ int len = arr.length; for (int i = 0; i < arr.length - 1; i++) { swap(arr, 0, len - 1); heapfiy(arr, 0, --len); } System.out.println("++++++++++++++++++"); for (int i : arr) { System.out.print (i+" "); } System.out.println(); System.out.println("++++++++++++++++++"); } }