开始设计
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user