Files
cKit/String/c_AmericanFlag.c
2026-08-31 22:49:42 +08:00

311 lines
11 KiB
C
Raw Permalink 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_AmericanFlag.h>
#include <c_ArrayStack.h>
#define COMPONENT_AFS_CUTOFF 15
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
/**
* @brief 内部原子物理接口:泛型就地连续内存块高效对调
*/
C_STATIC_FORCE_INLINE
void c_AFS_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_AFS_CascadedCompare(const void* a, const void* b, c_size_t start_d, c_AFS_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;
}
}
/**
* @brief 降级优化专线:泛型后缀级联插入排序
*/
static void c_AFS_InsertionSort(char* base, c_size_t low, c_size_t high, c_size_t elem_size, c_AFS_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_AFS_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_AmericanFlagSort_Recursive(char* base, c_size_t low, c_size_t high, c_size_t elem_size, c_AFS_ExtractorFn extractor, c_size_t d, void* args) {
if (high <= low || high == (c_size_t)-1) {
return;
}
if (high - low < COMPONENT_AFS_CUTOFF) {
c_AFS_InsertionSort(base, low, high, elem_size, extractor, d, args);
return;
}
// 🌟【规范统一字符表】:终止符 -1 映射到桶 0,普通字节 0~255 映射到桶 1~256,总上限 257
#define C_AFS_R 257
c_size_t count[C_AFS_R];
c_size_t head[C_AFS_R];
c_size_t end[C_AFS_R]; // 🌟【右边界加固锁】:死死锁存每个桶的绝对开区间截止端点
memset(count, 0, sizeof(count));
// 步骤 1:频率扫描计数
for (c_size_t i = low; i <= high; i++) {
int c = extractor(base + (i * elem_size), d, args);
count[c + 1]++;
}
// 步骤 2:精准增量式计算每个桶在连续内存 [low, high] 中的物理起始与截止配额
c_size_t current_offset = low;
for (int r = 0; r < C_AFS_R; r++) {
head[r] = current_offset;
current_offset += count[r];
end[r] = current_offset;
}
// 克隆一份绝对不会被置换扭转污染的初始边界快照 sub_bounds,专门供后续级联多路分治递归定位安全区
c_size_t sub_bounds[C_AFS_R];
memcpy(sub_bounds, head, sizeof(head));
// 步骤 3:🌟🌟🌟【美国国旗就地多路环置换绝对内核】🌟🌟🌟
for (int r = 0; r < C_AFS_R; r++) {
while (head[r] < end[r]) {
// 每次进入循环体,必须动态基于当前的 head[r] 最新游标地址执行一维寻址定位
char* curr_elem = base + (head[r] * elem_size);
// 🌟【重新特征提取联锁】:动态计算出换进来的新元素的正确目标桶
int c = extractor(curr_elem, d, args);
int c_slot = c + 1;
// 情况 A:元素本就属于当前正在梳理的桶 r,无需置换,当前桶游标单调步进滑过
if (c_slot == r) {
head[r]++;
}
// 情况 B:属于外部其他桶,且那个目标桶目前尚未满员(head < end 锁有效拦截)
else if (head[c_slot] < end[c_slot]) {
c_size_t dest_pos = head[c_slot];
char* target_elem = base + (dest_pos * elem_size);
// 执行就地泛型物理互换。当前 head[r] 游标指针在原地坚守守候!
// 在下一轮 while 循环中,由于前面的重提取联锁,会立刻对被对调过来的数据执行哈希哈希特征重提取
c_AFS_InternalSwap(curr_elem, target_elem, elem_size);
head[c_slot]++;
}
// 情况 C:属于外部其他桶,但目标桶在前面已被前置填满(head >= end
else {
// 说明由于大规模随机碰撞分配它不得不中途暂存,直接向前强行合拢,滑过处理
head[r]++;
}
}
}
// 步骤 4:级联多路分治深层递归(桶 0 对应的终止符 -1 属于完结节点,果断跳过不递归)
for (int r = 1; r < C_AFS_R; r++) {
c_size_t next_low = sub_bounds[r];
c_size_t next_high = end[r] - 1;
if (next_high > next_low && next_high != (c_size_t)-1) {
c_AmericanFlagSort_Recursive(base, next_low, next_high, elem_size, extractor, d + 1, args);
}
}
#undef C_AFS_R
}
/**
* @brief 工业级纯就地、零动态堆内存损耗泛型美国国旗排序标准对外总线入口
*/
c_err_t c_AmericanFlag_Sort(void* base, c_size_t num, c_size_t elem_size, c_AFS_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_AmericanFlagSort_Recursive(array_base, 0, num - 1, elem_size, extractor, 0, args);
return C_ERR_OK;
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
// 显式转储栈的最大深度上限(足以承载 1024 层深度的字符串级联下探,物理隔离栈溢出)
#define COMPONENT_NAFS_STACK_MAX 1024
typedef struct {
c_size_t low; // 当前待处理区间的左闭端点物理下标
c_size_t high; // 当前待处理区间的右闭端点物理下标
c_size_t d; // 当前执行分桶扫描的第 d 个无符号字节游标位置
} c_NAFS_Frame_t;
c_err_t c_AmericanFlag_NonRecSort(void* base, c_size_t num, c_size_t elem_size, c_AFS_ExtractorFn extractor, void* args, c_Allocator_t* allocator) {
if (!base || elem_size == 0 || !extractor) {
return C_ERR_PARAM;
}
if (num < 2) {
return C_ERR_OK; // 零体安全放行
}
char* array_base = (char*)base;
// 🌟【非递归核心防线】:在栈空间建立显式帧管理矩阵,将弹跳开销控制在确定常量内
c_ArrayStack_t stack;
c_ArrayStack_Init(&stack, sizeof(c_NAFS_Frame_t), 1024, allocator);
// c_NAFS_Frame_t stack[COMPONENT_NAFS_STACK_MAX];
// c_size_t stack_size = 0;
// 初始首帧压栈:区间为 [0, num-1],高位起始字节 d = 0
// stack[stack_size].low = 0;
// stack[stack_size].high = num - 1;
// stack[stack_size].d = 0;
// stack_size++;
c_NAFS_Frame_t frame;
frame.low = 0;
frame.high = num - 1;
frame.d = 0;
c_ArrayStack_Push(&stack, &frame);
#define C_AFS_R 257
c_size_t count[C_AFS_R];
c_size_t head[C_AFS_R];
c_size_t end[C_AFS_R];
c_size_t sub_bounds[C_AFS_R];
// 启动非递归主迭代滑窗
while (!c_ArrayStack_IsEmpty(&stack)) {
// 出栈当前待处理的帧载体
// stack_size--;
// c_size_t low = stack[stack_size].low;
// c_size_t high = stack[stack_size].high;
// c_size_t d = stack[stack_size].d;
c_ArrayStack_Pop(&stack, &frame);
c_size_t low = frame.low;
c_size_t high = frame.high;
c_size_t d = frame.d;
// 极限拦截
if (high <= low || high == (c_size_t)-1) {
continue;
}
// 优化点 1:小区间降级截断,直接走快速就地级联插入专线
if (high - low < COMPONENT_AFS_CUTOFF) {
c_AFS_InsertionSort(array_base, low, high, elem_size, extractor, d, args);
continue;
}
memset(count, 0, sizeof(count));
// 1. 频率扫描计数
for (c_size_t i = low; i <= high; i++) {
int c = extractor(array_base + (i * elem_size), d, args);
count[c + 1]++;
}
// 2. 精确增量式计算每个桶在当前闭区间内绝对物理起始与截止配额
c_size_t current_offset = low;
for (int r = 0; r < C_AFS_R; r++) {
head[r] = current_offset;
current_offset += count[r];
end[r] = current_offset;
}
// 锁存绝对不变的初始边界快照
memcpy(sub_bounds, head, sizeof(head));
// 3. 🌟🌟🌟【环置换无损对调核心状态机(Dynamic Remap Lock)】🌟🌟🌟
for (int r = 0; r < C_AFS_R; r++) {
while (head[r] < end[r]) {
char* curr_elem = array_base + (head[r] * elem_size);
int c = extractor(curr_elem, d, args);
int c_slot = c + 1;
if (c_slot == r) {
head[r]++;
}
else if (head[c_slot] < end[c_slot]) {
c_size_t dest_pos = head[c_slot];
char* target_elem = array_base + (dest_pos * elem_size);
c_AFS_InternalSwap(curr_elem, target_elem, elem_size);
head[c_slot]++;
}
else {
head[r]++;
}
}
}
// 4. 🌟【迭代变轨核心】:将后续的多路深度分治区间逆向压入显式栈中
// 注意:桶 0 对应的终止符 -1 属于完结节点,彻底剔除不入栈
for (int r = C_AFS_R - 1; r >= 1; r--) {
c_size_t next_low = sub_bounds[r];
c_size_t next_high = end[r] - 1;
if (next_high > next_low && next_high != (c_size_t)-1) {
// 状态检查:防止极限特种输入冲破显式栈容量
// if (stack_size < COMPONENT_NAFS_STACK_MAX) {
// stack[stack_size].low = next_low;
// stack[stack_size].high = next_high;
// stack[stack_size].d = d + 1; // 字节游标单调向右推
// stack_size++;
// }
frame.low = next_low;
frame.high = next_high;
frame.d = d+1;
c_ArrayStack_Push(&stack, &frame);
}
}
}
#undef C_AFS_R
c_ArrayStack_Destroy(&stack);
return C_ERR_OK;
}