使用 C++ 標準庫函式(如 qsort 或 std::sort)對結構體陣列進行多欄位排序時,若直接傳遞單一比較函數指標,難以處理「先按欄位 A 排序,相同再按欄位 B 排序」的邏輯,導致排序結果錯亂。
關鍵在於編寫一個複合比較函數,在單一比較邏輯中依序判斷多個欄位。此函數作為排序演算法的比較器參數傳入。
qsort(C 風格)#include <stdlib.h>
#include <string.h>
typedef struct {
int field1;
int field2;
char name[32];
} Record;
int compare_records(const void *a, const void *b) {
const Record *ra = (const Record *)a;
const Record *rb = (const Record *)b;
// 第一優先級:field1 遞增
if (ra->field1 != rb->field1)
return ra->field1 - rb->field1;
// 第二優先級:field2 遞減
if (ra->field2 != rb->field2)
return rb->field2 - ra->field2; // 反向
// 第三優先級:name 字典序
return strcmp(ra->name, rb->name);
}
// 呼叫
qsort(array, count, sizeof(Record), compare_records);
std::sort(C++ 風格,推薦)#include <algorithm>
#include <vector>
#include <string>
struct Record {
int field1;
int field2;
std::string name;
};
bool compare_records(const Record& a, const Record& b) {
if (a.field1 != b.field1) return a.field1 < b.field1; // 遞增
if (a.field2 != b.field2) return a.field2 > b.field2; // 遞減
return a.name < b.name; // 字典序
}
// 呼叫
std::vector vec = ...;
std::sort(vec.begin(), vec.end(), compare_records);
std::sort(vec.begin(), vec.end(), [](const Record& a, const Record& b) {
if (a.field1 != b.field1) return a.field1 < b.field1;
if (a.field2 != b.field2) return a.field2 > b.field2;
return a.name < b.name;
});
a - b 可能溢位,建議用 (a > b) - (a < b) 或三元運算子。std::sort 行為未定義。==,需設定容差 epsilon。更多範例可參考:CSDN 部落格:C++ 結構體多欄位排序
C++ 結構體陣列多鍵值排序的核心是編寫複合比較器,在單一函數中依優先級順序判斷各欄位。推薦使用 std::sort 搭配 Lambda,型別安全且效能優於 qsort。