This commit is contained in:
2026-08-31 22:49:42 +08:00
parent 109e8af3d5
commit 4e5ae52e54
35 changed files with 3606 additions and 22 deletions
+159
View File
@@ -0,0 +1,159 @@
#include <c_Quick3string.h>
// 小区间自适应截断降级阈值(小于此体量的碎区间直接交付级联插入排序专线)
#define COMPONENT_Q3S_CUTOFF 15
/**
* @brief 内部原子物理接口:泛型就地连续内存块对调
*/
C_STATIC_FORCE_INLINE
void c_Q3S_InternalSwap(void* a, void* b, c_size_t size) {
if (a == b) return;
char* p1 = (char*)a;
char* p2 = (char*)b;
char temp_buf[256];
c_size_t bytes_left = size;
while (bytes_left > 0) {
c_size_t chunk = (bytes_left < sizeof(temp_buf)) ? bytes_left : sizeof(temp_buf);
memcpy(&temp_buf, p1, chunk);
memcpy(p1, p2, chunk);
memcpy(p2, &temp_buf, chunk);
p1 += chunk;
p2 += chunk;
bytes_left -= chunk;
}
}
/**
* @brief 带起始偏移量 d 的全景多级深度级联字典序比对器
*/
C_STATIC_FORCE_INLINE
int c_Q3S_CascadedCompare(const void* a, const void* b, c_size_t start_d, c_Q3S_ExtractorFn extractor, void* args) {
c_size_t cur_d = start_d;
while (1) {
int char_a = extractor(a, cur_d, args);
int char_b = extractor(b, cur_d, args);
if (char_a == char_b) {
if (char_a == -1) return 0; // 双方完全全等
cur_d++;
continue;
}
return char_a - char_b; // 截止符 -1 属于绝对极小值
}
}
/**
* @brief 降级优化专线:泛型后缀级联插入排序
*/
static void c_Q3S_InsertionSort(char* base, c_size_t low, c_size_t high, c_size_t elem_size, c_Q3S_ExtractorFn extractor, c_size_t d, void* args) {
for (c_size_t i = low + 1; i <= high; i++) {
c_size_t j = i;
char* item_i = base + (i * elem_size);
char v_buf[elem_size];
memcpy(v_buf, item_i, elem_size);
while (j > low) {
char* previous = base + ((j - 1) * elem_size);
char* current = base + (j * elem_size);
if (c_Q3S_CascadedCompare(v_buf, previous, d, extractor, args) < 0) {
memcpy(current, previous, elem_size);
j--;
} else {
break;
}
}
memcpy(base + (j * elem_size), v_buf, elem_size);
}
}
/**
* @brief 三向字符串快速排序递归控制核心状态机(无符号全加固闭区间版)
*/
static void c_Quick3string_Recursive(char* base, c_size_t low, c_size_t high, c_size_t elem_size, c_Q3S_ExtractorFn extractor, c_size_t d, void* args) {
// 🌟【无符号下溢强拦截】:若当前区间上限发生下溢跨步或者区间非法,果断前置熔断破出
if (high <= low || high == (c_size_t)-1) {
return;
}
// 1. 小数组降级截断,彻底抹杀高维分治在稀疏碎片子树下的常数延迟
if (high - low < COMPONENT_Q3S_CUTOFF) {
c_Q3S_InsertionSort(base, low, high, elem_size, extractor, d, args);
return;
}
// 2. 选择当前区间的首元素作为三向切分的基准锚定点(Pivot)
char* pivot_item = base + (low * elem_size);
int v = extractor(pivot_item, d, args);
// 🌟【双指针向内对碰状态机控制线】:
// lt 游标代表小于 v 区间的右开端点;gt 游标代表大于 v 区间的左闭端点;i 为当前探测移动指针
c_size_t lt = low;
c_size_t i = low + 1;
c_size_t gt = high;
// 3. 核心分治走查循环
while (i <= gt && gt != (c_size_t)-1) {
char* curr_item = base + (i * elem_size);
int t = extractor(curr_item, d, args);
if (t < v) {
// 情况 A:当前字符小于切分字符,与 lt 位置就地物理对调,两组游标同步推进
c_Q3S_InternalSwap(base + (lt * elem_size), curr_item, elem_size);
lt++;
i++;
}
else if (t > v) {
// 情况 B:当前字符大于切分字符,与当前的 gt 尾部边缘插槽执行就地 Swap 对调
c_Q3S_InternalSwap(curr_item, base + (gt * elem_size), elem_size);
// 🌟 绝杀点:gt 减法单调向左逼近。为了防止其减到 0 之后发生回绕下溢,
// 增设了严格的高位联锁前置判定,若 gt 已经逼近最左端,强制使其归 `-1` 并斩断 while
if (gt == 0) {
gt = (c_size_t)-1;
} else {
gt--;
}
// 注意:此时探测指针 i 保持原地不动!换进来的新内容会在下一轮循环被重新审讯判定
}
else {
// 情况 C:完全相等,无伤安全滑过,游标递增
i++;
}
}
// 4. 🌟🌟🌟【级联分治三向并行递归管线】🌟🌟🌟
// 区间 1:递归对左侧完全 [low, lt - 1] 的“小于区”执行排序。第 d 位字符保持不变
if (lt > 0 && (lt - 1) > low) {
c_Quick3string_Recursive(base, low, lt - 1, elem_size, extractor, d, args);
}
// 区间 2:递归对中央 [lt, gt] 的“等于区”执行排序!
// 核心精髓:由于这个子区间的所有元素在第 d 位字符上已经百分之百全等,
// 我们的字节提取器游标 d + 1 单调向右推前移,彻底略过已对齐前缀,执行深层后缀的对碰。
// 特殊拦截:若当前切分出的基准字符本身就是终止哨兵 -1,说明这批等于区的字符串内容在物理上已经提前完结,果断斩断深层递归,不进入 d+1
if (v >= 0 && gt != (c_size_t)-1 && gt >= lt) {
c_Quick3string_Recursive(base, lt, gt, elem_size, extractor, d + 1, args);
}
// 区间 3:递归对右侧 [gt + 1, high] 的“大于区”执行排序。第 d 位字符保持不变
if (gt != (c_size_t)-1 && high > (gt + 1)) {
c_Quick3string_Recursive(base, gt + 1, high, elem_size, extractor, d, args);
}
}
/**
* @brief 工业级变长泛型三向字符串快速排序标准对外总线入口
*/
c_err_t c_Quick3string(void* base, c_size_t num, c_size_t elem_size, c_Q3S_ExtractorFn extractor, void* args) {
if (!base || elem_size == 0 || !extractor) {
return C_ERR_PARAM;
}
if (num < 2) {
return C_ERR_OK; // 零体安全放行
}
char* array_base = (char*)base;
c_Quick3string_Recursive(array_base, 0, num - 1, elem_size, extractor, 0, args);
return C_ERR_OK;
}