#include "c_InplaceMSD.h" #include "c_Test.h" #include #include static int string_msd_extractor(const void* elem, c_size_t d, void* args) { (void)args; const char* str = *(const char* const*)elem; c_size_t len = strlen(str); if (d >= len) return -1; return (int)((unsigned char)str[d]); } TEST_CASE(test_c_InPlace_MSD_RadixSort_VariableStrings) { // 构造一个包含 18 个元素、大量前缀交织("shor", "shore", "short", "sh")的变长恶劣方阵 const char* arr[] = { "she", "sells", "seashells", "by", "the", "sea", "shore", "the", "shells", "she", "sea", "shore", "sit", "short", "shor", "a", "sh", "z" }; c_size_t num = sizeof(arr) / sizeof(arr[0]); // 调用纯就地 MSD 排序,零动态辅助缓冲分配 c_err_t err = c_InPlaceMSD_RadixSort(arr, num, sizeof(char*), string_msd_extractor, NULL); ASSERT_INT_EQ(C_ERR_OK, err); // 验证严格的全局字典序单调非减 for (c_size_t i = 0; i < num - 1; i++) { if (strcmp(arr[i], arr[i + 1]) > 0) { printf(" " COLOR_RED "[FAIL] 就地置换错位捕获: arr[%d]='%s' 排在 arr[%d]='%s' 的前面!" COLOR_RESET "\n", (int)i, arr[i], (int)(i + 1), arr[i + 1]); ASSERT_TRUE(false); return; } } // 校验极短终止符和极长串的拓扑归位状态 ASSERT_TRUE(strcmp("a", arr[0]) == 0); ASSERT_TRUE(strcmp("by", arr[1]) == 0); ASSERT_TRUE(strcmp("sea", arr[2]) == 0); // 极短终止符前缀必须完美垫底最前端 ASSERT_TRUE(strcmp("shells", arr[9]) == 0); // 极短终止符前缀必须完美垫底最前端 ASSERT_TRUE(strcmp("shor", arr[10]) == 0); ASSERT_TRUE(strcmp("shore", arr[11]) == 0); ASSERT_TRUE(strcmp("z", arr[num - 1]) == 0); // 尾部大收拢正确 } // ========================================== // 新增测试:强迫其在顶层就少于15个元素,精准覆盖降级插入排序专线 // ========================================== TEST_CASE(test_c_InPlaceMSD_RadixSort_DirectInsertionSortCutoff) { // 🌟 故意精简至 10 个数据(小于阈值 15),且打乱顺序、包含相同前缀和变长终止符 const char* arr_short[] = { "shore", "she", "sells", "sea", "sh", "shor", "sit", "short", "a", "sea" }; c_size_t num = sizeof(arr_short) / sizeof(arr_short[0]); // 调用入口:在第 0 字节探测时就因为总数 10 < 15 爆发降级,直接由 c_IP_MSD_InsertionSort 接管 c_err_t err = c_InPlaceMSD_RadixSort(arr_short, num, sizeof(char*), string_msd_extractor, NULL); ASSERT_INT_EQ(C_ERR_OK, err); // 验证降级插入排序后的全局字典序是否完全单调非减 for (c_size_t i = 0; i < num - 1; i++) { if (strcmp(arr_short[i], arr_short[i + 1]) > 0) { printf(" " COLOR_RED "[FAIL] 降级插入排序错位: arr_short[%d]='%s' 居然排在 arr_short[%d]='%s' 前面!" COLOR_RESET "\n", (int)i, arr_short[i], (int)(i + 1), arr_short[i + 1]); ASSERT_TRUE(false); return; } } // 验证级联插入排序对短前缀终止符与后缀字典序的排序正确性 ASSERT_TRUE(strcmp("a", arr_short[0]) == 0); ASSERT_TRUE(strcmp("sea", arr_short[1]) == 0); ASSERT_TRUE(strcmp("sea", arr_short[2]) == 0); // 稳定排序项紧凑排布 ASSERT_TRUE(strcmp("sh", arr_short[4]) == 0); // 短前缀完美垫底 ASSERT_TRUE(strcmp("shor", arr_short[6]) == 0); ASSERT_TRUE(strcmp("shore", arr_short[7]) == 0); ASSERT_TRUE(strcmp("short", arr_short[8]) == 0); ASSERT_TRUE(strcmp("sit", arr_short[num-1]) == 0); } int main(void) { TEST_START(C_InPlace_MSD_RadixSort_TestSuite); RUN_TEST(test_c_InPlace_MSD_RadixSort_VariableStrings); RUN_TEST(test_c_InPlaceMSD_RadixSort_DirectInsertionSortCutoff); TEST_REPORT(); return (g_test_registry.failed_count > 0 ? 1 : 0); }