Files
cAI/cKit/Sort/c_ShellSort.t.c
T
2026-08-10 01:21:15 +08:00

117 lines
4.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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;
}