Files
cAI/cKit/Sort/c_LSDRadixSort.c
T

63 lines
2.3 KiB
C
Raw Normal View History

2026-08-10 01:21:15 +08:00
#include <c_LSDRadixSort.h>
#include <c_Memory.h>
/**
* Sorts an array of fixed-length strings stably using the LSD Radix Sort pipeline.
* Features upfront workspace allocations to completely eliminate heap thrashing in hot loops.
*
* Time Complexity: O(W * (N + R)) | Space Complexity: O(N + R) transient workspace memory
* @param sort Pointer to the initialized LSD config profile.
* @param arr Array of pointers to null-terminated char arrays (each must be at least W long).
* @param n Total number of strings inside the array.
*/
c_err_t c_LSDRadixSort_Sort(const c_LSDRadixSort_t* sort, char** arr, c_size_t n) {
if (sort == NULL || arr == NULL || sort->R == 0 || sort->W == 0) return C_ERR_PARAM;
if (n <= 1) return C_ERR_OK; // Trivial exit pass
c_size_t R = sort->R;
c_size_t W = sort->W;
// Upfront Transient Workspace Allocation: Eliminates allocation overhead in hot paths
char** aux = (char**)C_ALLOC(n * sizeof(char*));
c_size_t* count = (c_size_t*)C_ALLOC((R + 1) * sizeof(c_size_t));
if (aux == NULL || count == NULL) {
C_FREE(aux);
C_FREE(count);
return C_ERR_NOMEM;
}
// --- Core Iterative LSD Pass Loop ---
// Travel from right to left (Least Significant to Most Significant)
for (long long d = (long long)W - 1; d >= 0; d--) {
// Reset the counting frequency registers
memset(count, 0, (R + 1) * sizeof(c_size_t));
// Pass A: Compute frequency counts using character indices as bucket addresses
for (c_size_t i = 0; i < n; i++) {
unsigned char c = (unsigned char)arr[i][d];
count[c + 1]++;
}
// Pass B: Transform frequencies into structural start indexes (Prefix Sums)
for (c_size_t r = 0; r < R; r++) {
count[r + 1] += count[r];
}
// Pass C: Distribute strings to the temporary aux array (Guarantees Stable Order Sorting)
for (c_size_t i = 0; i < n; i++) {
unsigned char c = (unsigned char)arr[i][d];
aux[count[c]++] = arr[i];
}
// Pass D: Copy back copies natively to the primary tracking layout pointers
memcpy(arr, aux, n * sizeof(char*));
}
// Purge temporary scratchpad workspace containers cleanly
C_FREE(aux);
C_FREE(count);
return C_ERR_OK;
}