Files

117 lines
4.0 KiB
C
Raw Permalink Normal View History

2026-08-10 01:21:15 +08:00
#include "c_ShellSort.h"
#include <stdlib.h>
#include <stdio.h>
// 单元测试断言宏
#define EXPECT_TRUE(cond, msg) \
do { \
if (!(cond)) { printf(" [X] 失败: %s\n", msg); return false; } \
} while(0)
// 复杂结构体元素:员工信息(用于小内存/栈分配测试)
typedef struct {
int id;
char name[16];
int score;
} Employee;
// 极其庞大的结构体元素(用于逼出堆分配测试,超过 STACK_LIMIT
typedef struct {
int id;
char massive_payload[256]; // 超过 128 字节限制
} LargeTask;
// 1. 比较器:按员工积分 (score) 升序
int compareEmpByScore(const void* a, const void* b) {
const Employee* e1 = (const Employee*)a;
const Employee* e2 = (const Employee*)b;
return (e1->score > e2->score) - (e1->score < e2->score);
}
// 2. 比较器:按大任务 ID 降序
int compareTaskByIdDesc(const void* a, const void* b) {
const LargeTask* t1 = (const LargeTask*)a;
const LargeTask* t2 = (const LargeTask*)b;
return (t2->id > t1->id) - (t2->id < t1->id);
}
// 3. 比较器:普通整型升序
int compareInt(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}
// 测试用例 1:极限边界(空数组或单元素数组不崩溃)
bool test_boundary_cases() {
int* empty_arr = NULL;
c_ShellSort(empty_arr, 0, sizeof(int), compareInt); // 传 NULL 不应崩溃
int single_elem[] = { 42 };
c_ShellSort(single_elem, 1, sizeof(int), compareInt); // 1个元素不处理
EXPECT_TRUE(single_elem[0] == 42, "单元素数组值被篡改");
return true;
}
// 测试用例 2:完全逆序数组的排序(触发大量 Gap 步进调整)
bool test_reverse_array() {
Employee emps[] = {
{4, "Manager", 90},
{3, "Leader", 80},
{2, "Senior", 70},
{1, "Junior", 60}
};
c_size_t num = sizeof(emps) / sizeof(emps[0]);
c_ShellSort(emps, num, sizeof(Employee), compareEmpByScore);
// 预期结果:按积分 60, 70, 80, 90 升序
EXPECT_TRUE(emps[0].score == 60 && emps[3].score == 90, "逆序数组排序未完全生效");
for(c_size_t i = 0; i < num - 1; i++) {
EXPECT_TRUE(emps[i].score <= emps[i+1].score, "逆序序列排序后仍不满足单调递增");
}
return true;
}
// 测试用例 3:包含大量相同主键的复杂数组(测试减治和覆盖分支)
bool test_duplicate_keys() {
Employee emps[] = {
{1, "A", 100}, {2, "B", 50}, {3, "C", 100}, {4, "D", 50}, {5, "E", 100}
};
c_size_t num = sizeof(emps) / sizeof(emps[0]);
c_ShellSort(emps, num, sizeof(Employee), compareEmpByScore);
EXPECT_TRUE(emps[0].score == 50 && emps[1].score == 50, "相同项未能归拢到前半段");
EXPECT_TRUE(emps[2].score == 100 && emps[4].score == 100, "相同项未能归拢到后半段");
return true;
}
// 测试用例 4:大体积结构体(单元素 > 128 字节,强制触发 C_ALLOC 堆内存分配)
bool test_large_struct_heap() {
LargeTask tasks[] = {
{10, "Payload A"}, {99, "Payload B"}, {5, "Payload C"}, {40, "Payload D"}
};
c_size_t num = sizeof(tasks) / sizeof(tasks[0]);
// 采用【降序】比较器
c_ShellSort(tasks, num, sizeof(LargeTask), compareTaskByIdDesc);
// 预期结果:ID 降序排序 -> 99, 40, 10, 5
EXPECT_TRUE(tasks[0].id == 99, "堆分配大结构体首位未命中最大值");
EXPECT_TRUE(tasks[3].id == 5, "堆分配大结构体末位未命中最小值");
return true;
}
int main() {
printf("=== 开始 c_ShellSort 框架级单元测试 ===\n");
if (test_boundary_cases()) printf("[PASS] 用例 1: 极限边界条件测试通过\n");
if (test_reverse_array()) printf("[PASS] 用例 2: 逆序复杂元素排序通过\n");
if (test_duplicate_keys()) printf("[PASS] 用例 3: 密集重复键稳定性分支通过\n");
if (test_large_struct_heap()) printf("[PASS] 用例 4: 堆分配(>128B)大元素排序通过\n");
printf("\n=== 所有测试执行完毕 ===\n");
return 0;
}