<stdlib.h>void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));O(n log n),最壞 O(n²)(已優化版本如 glibc 內部切換插入排序緩解)。std::sort(<algorithm>),類型安全、更快、支援仿函數/lambda。int cmp(const void* a, const void* b) {
// 1. 強制轉型為元素指針
// 2. 比較邏輯
// 3. 返回:負值(<)、0(=)、正值(>)
}
int cmp_int(const void* a, const void* b) {
int ia = *(const int*)a;
int ib = *(const int*)b;
return (ia > ib) - (ia < ib); // 避免相減溢出
}
int cmp_double(const void* a, const void* b) {
double da = *(const double*)a;
double db = *(const double*)b;
return (da > db) - (da < db); // 同理避免 NaN 問題
}
struct Student { double score; int id; };
int cmp_score(const void* a, const void* b) {
double sa = ((const struct Student*)a)->score;
double sb = ((const struct Student*)b)->score;
return (sa > sb) - (sa < sb);
}
struct Point { int x, y; };
int cmp_point(const void* a, const void* b) {
const struct Point* pa = (const struct Point*)a;
const struct Point* pb = (const struct Point*)b;
if (pa->x != pb->x) return pa->x - pb->x; // x 升序
return pb->y - pa->y; // y 降序
}
int cmp_str(const void* a, const void* b) {
const char* sa = *(const char**)a; // 若陣列存指針
const char* sb = *(const char**)b;
return strcmp(sa, sb);
}
// 或結構體內嵌字符數組
struct Item { char name[32]; };
int cmp_item(const void* a, const void* b) {
return strcmp(((const struct Item*)a)->name, ((const struct Item*)b)->name);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student { char name[20]; int score; };
int cmp_stu(const void* a, const void* b) {
const struct Student* p1 = (const struct Student*)a;
const struct Student* p2 = (const struct Student*)b;
if (p1->score != p2->score) return p2->score - p1->score; // 分數降序
return strcmp(p1->name, p2->name); // 同分按姓名升序
}
int main() {
struct Student arr[] = {
{"Alice", 85}, {"Bob", 92}, {"Charlie", 85}, {"David", 78}
};
size_t n = sizeof(arr) / sizeof(arr[0]);
qsort(arr, n, sizeof(arr[0]), cmp_stu);
for (size_t i = 0; i < n; ++i)
printf("%s %d\n", arr[i].name, arr[i].score);
return 0;
}
bool 或只返回 0/1:必須返回負/0/正,否則排序結果未定義。return *a - *b 在 INT_MIN - INT_MAX 溢出,改用 (*a > *b) - (*a < *b)。const 正確性:比較函數參數應為 const void*,轉型時保留 const。base 傳 arr,size 為元素大小(如 sizeof(arr[0]) 或 sizeof(char*))。#include <algorithm>
#include <vector>
#include <string>
std::vector<Student> vec = ...;
std::sort(vec.begin(), vec.end(),
[](const Student& a, const Student& b) {
if (a.score != b.score) return a.score > b.score;
return a.name < b.name;
});
O(n log n),通常比 qsort 快 2-3 倍。qsort 是 C 語言通用排序的基石,掌握比較函數編寫技巧(特別是多級排序、避免溢出、浮點處理)至關重要。C++ 專案請優先使用 std::sort,代碼更簡潔、安全、高效。