#ifndef INCLUDED_C_QUICKSORTITERATIVE_H #define INCLUDED_C_QUICKSORTITERATIVE_H #ifndef INCLUDED_C_BASE_H #include #endif /*INCLUDED_C_BASE_H*/ #ifndef INCLUDED_C_MEMORY_H #include #endif /*INCLUDED_C_MEMORY_H*/ /* ------------------------------------------------------------------------------------------------------------------ */ /* */ /** * Internal macro helper to swap two arbitrary blocks of memory. */ C_STATIC_FORCE_INLINE void c_SwapInternal(char* a, char* b, c_size_t size, void* temp) { if (a == b) return; memcpy(temp, a, size); memcpy(a, b, size); memcpy(b, temp, size); } /** * Standard Lomuto or Hoare-style tracking partition loop. * Uses the rightmost element as the pivot for flat linear execution. */ C_STATIC_FORCE_INLINE long long c_PartitionIterative(char* arr, long long left, long long right, c_size_t size, void* temp, int (*compar)(const void*, const void*)) { char* pivot = arr + (right * size); long long i = left - 1; for (long long j = left; j < right; j++) { if (compar(arr + (j * size), pivot) <= 0) { i++; c_SwapInternal(arr + (i * size), arr + (j * size), size, temp); } } c_SwapInternal(arr + ((i + 1) * size), arr + (right * size), size, temp); return (i + 1); } /** * Top-Level Custom Framework Entry Point for Non-Recursive Quicksort. * Time Complexity: O(n log n) average | Space Complexity: O(log n) explicit stack | Stable: No */ C_STATIC_FORCE_INLINE void c_QuickSortIterative(void* base, c_size_t num, c_size_t size, int (*compar)(const void*, const void*)) { if (base == NULL || num < 2 || size == 0) return; char* arr = (char*)base; // Optimization: Stack buffer allocation for pivot element swaps #define QSORT_STACK_LIMIT 128 char stack_buf[QSORT_STACK_LIMIT]; void* temp = (size <= QSORT_STACK_LIMIT) ? stack_buf : C_ALLOC(size); if (temp == NULL) return; // Allocate the explicit partition boundary stack. // Max required stack depth for range tracking is 2 * ceil(log2(num)) + 2. // For a 64-bit address space, 128 slots safely handles any possible array size. long long range_stack[128]; long long top = -1; // Push initial array boundaries onto the tracking stack range_stack[++top] = 0; range_stack[++top] = (long long)num - 1; // Keep processing partitions until the explicit boundary stack is empty while (top >= 0) { // Pop right and left boundaries long long right = range_stack[top--]; long long left = range_stack[top--]; // Execute linear pivot segmentation long long p = c_PartitionIterative(arr, left, right, size, temp, compar); // If there are elements on the left side of the pivot, push their range to the stack if (p - 1 > left) { range_stack[++top] = left; range_stack[++top] = p - 1; } // If there are elements on the right side of the pivot, push their range to the stack if (p + 1 < right) { range_stack[++top] = p + 1; range_stack[++top] = right; } } if (size > QSORT_STACK_LIMIT) { C_FREE(temp); } #undef QSORT_STACK_LIMIT } #endif /*INCLUDED_C_QUICKSORTITERATIVE_H*/