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個不同元素的隨機排列的平均比較次數是2N logNO(Nlog logN)
  • 時間複雜度:T(N)=O(NlogN)
  • 雖然堆排序給出最佳平均時間複雜度,但實際效果不如用Sedgewick增量序列的希爾排序
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章