18. 排序--堆排序
阿新 • • 發佈:2019-01-01
堆排序
堆排序的前身–選擇排序
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]);
}
}
時間複雜度:
堆排序的實現
以下兩種演算法實現的堆排序都是不穩定
演算法1
- 根據指定陣列建立最小堆
- 從最小堆中刪除最小元素並儲存起來
- 把之前儲存的元素賦給原陣列
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( - 需要額外的
O(N) 空間,並且複製元素需要時間
演算法2
- 根據指定陣列建立最大堆
- 將最大堆的最大元素(即陣列的首元素)與陣列的最末元素交換,並縮小最大堆的規模和調整最大堆
- 重複2,直到
N−1 次
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個不同元素的隨機排列的平均比較次數是
2NlogN−O(NloglogN) - 時間複雜度:
T(N)=O(NlogN) - 雖然堆排序給出最佳平均時間複雜度,但實際效果不如用Sedgewick增量序列的希爾排序