排序是數據處理基石。按時間複雜度分類:
堆排序以 原地排序、不穩定、最壞情況 O(n log n) 見長,無需額外內存,適合內存受限環境。
i 的左子 2i、右子 2i+1、父節點 i/2。n/2 向前遞歸 篩選,構建大根堆。n-1 次得升序序列。void Sift(RecordNode r[], int low, int high) {
int i = low, j = 2*i;
RecordNode tmp = r[i];
while (j <= high) {
if (j < high && r[j].key < r[j+1].key) ++j; // 取較大子節點
if (tmp.key >= r[j].key) break; // 滿足堆序
r[i] = r[j]; // 子節點上移
i = j; j = 2*i;
}
r[i] = tmp;
}
輸入:n 名學生,每條記錄含 考號、分數。要求按分數降序輸出排名,同分同名次。
struct Student {
int id; // 考號
double score; // 分數
int rank; // 名次(排序後計算)
};
void HeapSort(Student arr[], int n) {
// 1. 建立大根堆(按 score)
for (int i = n/2; i >= 1; --i)
Sift(arr, i, n);
// 2. 反復輸出堆頂並重建
for (int i = n; i > 1; --i) {
swap(arr[1], arr[i]); // 最大值移至末尾
Sift(arr, 1, i-1); // 剩餘元素重建堆
}
// 現在 arr[1..n] 為升序,需逆序或調整比較方向得降序
}
void ComputeRanks(Student arr[], int n) {
int rank = 1;
for (int i = n; i >= 1; --i) { // 從最高分遍歷
if (i < n && arr[i].score != arr[i+1].score)
rank = n - i + 1; // 分數變化,名次 = 已處理人數 + 1
arr[i].rank = rank;
}
}






n-1 次篩選每次 O(log n),總 O(n log n)(最好/平均/最壞一致)。std::stable_sort。std::make_heap、std::sort_heap 或 std::sort(內部混合快排/堆排/插排)。