#include #include "c_Random.h" void c_KnuthShuffle(void* base, c_size_t num, c_size_t size) { // 边界与防御性校验:元素少于2个或大小非法时无需洗牌 if (!base || num < 2 || size == 0) { return; } c_Random_Init(); char* array_base = (char*)base; // 采用局部栈分配缓冲区,避免堆内存分配开销,提升交换效率 // 256字节足够容纳绝大多数基础类型与常见的结构体 char temp_buf[256]; // 从后往前进行滑窗交换 for (c_size_t i = num; i > 1; i--) { c_size_t current_idx = i-1; // 安全地在 [0, i] 闭区间内抽取一个随机目标下标 // 依托您之前的去偏差 c_Random_RangeU64 确保概率绝对均等 c_size_t j = (c_size_t)c_Random_RangeU64(0, current_idx); // 如果抽中自身,则无需原地交换 if (current_idx == j) { continue; } // 计算需要交换的两个元素在内存中的绝对地址 char* elem_i = array_base + (current_idx * size); char* elem_j = array_base + (j * size); // 泛型就地内存交换 (In-place Swap) c_size_t bytes_to_swap = size; while (bytes_to_swap > 0) { c_size_t chunk = (bytes_to_swap < sizeof(temp_buf)) ? bytes_to_swap : sizeof(temp_buf); memcpy(temp_buf, elem_i, chunk); memcpy(elem_i, elem_j, chunk); memcpy(elem_j, temp_buf, chunk); elem_i += chunk; elem_j += chunk; bytes_to_swap -= chunk; } } }