標籤:array data 基本 swap wap i+1 儲存 完成 邏輯
排序演算法(二):堆排序-Java實現
首先對堆排序有個整體的認識,堆排序是一個不穩定的排序演算法,其平均時間複雜度為O(nlogn),空間複雜度O(1)。
那麼何為堆排序呢?所謂堆排序是藉助於堆的概念來完成的排序演算法,其是選擇排序中的一種,因此通過選擇排序來理解堆排序會更加容易一些
下面我們來看一下堆的概念,其實堆又是藉助於二叉樹的概念來定義,對於堆分為大頂堆和小頂堆兩種,下面用數學表示式來精確的描述如下:
假設我們使用array數組來儲存堆,因為大頂堆表述為 array[i] >=array[2*i+1] && array[i] >= array[2*1+2] , 小頂堆表示為array[i] <=array[2*i+1] && array[i] <= array[2*1+2], 但是值的注意的是array[2*i+1] 與array[2*i+2] 之間沒有大小約束關係
對於堆的基本定義我們已經很清晰了,下面我們將詳細的介紹一下堆排序的思路
堆排序的整體思路如下(以大頂堆為例說明,小頂堆同理哈)
- 根據大定堆的概念array[0]始終是最大的,因此與array[array.length-1]進行交換,此時就形成了 array[0].... array[array.length-2] 的無序數組和 array[array.length-1] 的有序數組
- 在1中形成的 array[0].... array[array.length-2] 無序數組中破壞了堆的特性,因此需要一次調整,調整從array.length-1處開始
-
- 首先找到array.length-1 父親節點,如果有左右孩子,進行比較進行交換,依次迴圈往前進行處理
3. 依照按照1,2步驟迴圈進行,直到排序完成
Java 實現代碼邏輯如下:
1 public class HeapSort { 2 3 public static void main(String[] args) { 4 int[] array = new int[]{5, 3, 6, 2, 1, 9, 4, 8, 7}; 5 6 HeapSort heapSort = new HeapSort(); 7 heapSort.heapSort(array); 8 9 for (int i = 0; i < array.length; i++) {10 System.out.print(array[i]+" ");11 }12 }13 14 15 public void heapSort(int[] array) {16 17 for (int i = 0; i < array.length; i++) {18 // 將array[array.length-1-i]建立為堆19 createMaxHeap(array, array.length - 1 - i);20 // 因為大頂堆,所以最大值始終處於array[0],21 // 交換array[0]與array[array.length-1-i]22 swap(array, 0, array.length - 1 - i);23 }24 }25 26 // 調整成堆27 private void createMaxHeap(int[] array, int lastIndex) {28 // 從當前位置的父親節點29 for (int i = (lastIndex - 1) / 2; i >= 0; i--) {30 // 記錄當前的位置節點31 int k = i;32 // 條件成立,則說明有孩子節點,此時判斷是否滿足堆的特性33 while (2 * k + 1 <= lastIndex) {34 // 預設左孩子為最大35 int biggerIndex = 2 * k + 1;36 // 在判斷一下看是否有右孩子37 if (biggerIndex < lastIndex) {38 // 如果存在右孩子,並且右孩子大,則將預設索引加139 if (array[biggerIndex] < array[biggerIndex + 1]) {40 biggerIndex++;41 }42 }43 44 // 此時在跟父親節點作比較45 if (array[k] < array[biggerIndex]) {46 swap(array, k, biggerIndex);47 } else { // 如果不小於則結束本次迴圈,下一個節點的比較48 break;49 }50 }51 }52 }53 54 // 交換兩個元素55 private void swap(int[] data, int i, int j) {56 if (i == j) {57 return;58 }59 data[i] = data[i] + data[j];60 data[j] = data[i] - data[j];61 data[i] = data[i] - data[j];62 }
部落格描述不對之處,請指正,希望給大家帶來協助,謝謝。
排序演算法(二):堆排序-Java實現