神級基礎排序——堆排序

堆排序的介紹

堆排序(Heapsort)是指利用堆積樹(堆)這種數據結構所設計的一種排序算法,它是選擇排序的一種。可以利用數組的特點快速定位指定索引的元素。堆分爲大根堆和小根堆,是完全二叉樹。

  • 完全二叉樹:除了最後一層之外的其他每一層都被完全填充,每一層從左到右的填充數據,不能空缺
  • 大根堆:任意一個節點的值均大於等於它的左右孩子的值,位於堆頂的節點值最大
  • 小根堆:任意一個節點的值均小於等於它的左右孩子的值,位於堆頂的節點值最小

本節分享的堆排序以大根堆爲例子,大根堆的圖示
在這裏插入圖片描述

講解鋪墊(及其重要)

實際上要排序的是一個數組 int[] arr={3, 4, 5, 6, 7, 0, 2, 9, 8},上面的堆是我們幻想出來的,然後知道了arr數組的下標 i 後,我們可以得出它的父節點是**(i-1)/ 2**,它的左孩子是2*i+1,它的右孩子是2*i+2

堆排序的實現步驟

  • 把一個數組調整爲大根堆(heapInsert)
    假設當前節點的下標爲i,那麼它的父親節點爲(i-1)/2,每次heapInsert的時候就把insert進來的節點與它的父親節點進行比較,比它的父節點大就交換,一直重複調整

  • 每次把堆頂放到最後的節點位置,然後調整整個堆爲大根堆(heapify)
    每次把堆頂的節點放到最後,然後堆大小減1,然後調整爲大根堆,一直重複,直到大根堆的大小爲0爲止

代碼實現

import java.util.Arrays;

/**
 * @author god-jiang
 * @date 2020/1/10
 */
public class HeapSort {

    //heapInsert就是建立大根堆
    public static void heapInsert(int[] arr, int index) {
        while (arr[index] > arr[(index - 1) / 2]) {
            swap(arr, index, (index - 1) / 2);
            index = (index - 1) / 2;
        }
    }

    //heapify就是把堆頂和最後一個數交換位置,然後堆的大小size--
    public static void heapify(int[] arr, int index, int size) {
        int left = 2 * index + 1;
        while (left < size) {
            int largest = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left;
            largest = arr[index] > arr[largest] ? index : largest;
            if (largest == index)
                break;
            swap(arr, index, largest);
            index = largest;
            left = 2 * index + 1;
        }
    }

    //交換兩個數
    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    //主函數
    public static void main(String[] args) {
        int[] arr = {3, 4, 5, 6, 7, 0, 1, 2, 9, 8};
        int size = arr.length;
        for (int i = 0; i < size; i++) {
            heapInsert(arr, i);
        }
        swap(arr, 0, --size);
        while (size > 0) {
            heapify(arr, 0, size);
            swap(arr, 0, --size);
        }
        System.out.println(Arrays.toString(arr));
    }
}

運行截圖

在這裏插入圖片描述

總結

堆排序是排序算法裏面比較經典的一個算法吧,它的時間複雜度爲O(NlogN)。建立堆的時間複雜度爲O(N),然後堆的調整每步都是O(logN),所以進行了heapify之後就是O(NlogN)。以上就是我對堆排序的整個過程的理解。

PS:覺得博主寫的不錯的點點贊,關注走一波,謝謝大家的支持了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章