1. 程式人生 > >18. 排序--堆排序

18. 排序--堆排序

堆排序

堆排序的前身–選擇排序

void Selection_Sort(ElementType[] A, int N) {
    for (int i = 0; i < N; i++) {
        // 從A[i]到A{N-1}中找到最小元,並將其位置賦給MinPosition
        MinPosition = ScanForMin(A, i, N - 1);

        // 將未排序部分的最小元換到有序部分的最後位置
        Swap(A[i], A[MinPosition]);
    }
}

時間複雜度:T=Θ(N2)

堆排序的實現

以下兩種演算法實現的堆排序都是不穩定

演算法1

  1. 根據指定陣列建立最小堆
  2. 從最小堆中刪除最小元素並儲存起來
  3. 把之前儲存的元素賦給原陣列
void Heap_Sort(ElementType[] A, int N) {
    BuildMinHeap(A);    // 時間複雜度:O(N)
    for (i = 0; i < N; i++)
        Temp[i] = DeleteMin(A); // 時間複雜度:O(logN)
    for (i = 0; i < N; i++)     // 時間複雜度:O(N)
        A[i] = Temp[i];
}
  • 時間複雜度:T(N)=O(
    NlogN)
  • 需要額外的O(N)空間,並且複製元素需要時間

演算法2

  1. 根據指定陣列建立最大堆
  2. 將最大堆的最大元素(即陣列的首元素)與陣列的最末元素交換,並縮小最大堆的規模和調整最大堆
  3. 重複2,直到N1
void Heap_Sort(ElementType[] A, int N) {
    for (i = N/2 - 1; i >= 0; i--)  // 建立最大堆
        PercDown(A, i, N);  // 調整最大堆

    for (i = N - 1; i > 0; i--) {
        Swap(A[0], A[i]);   // 相當於刪去最大堆的頂上元素
PercDown(A, 0, i); // 調整最大堆 } }
  • 定理:堆排序處理N個不同元素的隨機排列的平均比較次數是2NlogNO(NloglogN)
  • 時間複雜度:T(N)=O(NlogN)
  • 雖然堆排序給出最佳平均時間複雜度,但實際效果不如用Sedgewick增量序列的希爾排序