55 lines
1.5 KiB
C
55 lines
1.5 KiB
C
#ifndef INCLUDED_C_MERGESORT_H
|
|||
|
|
#define INCLUDED_C_MERGESORT_H
|
||
|
|
|
||
|
|
#ifndef INCLUDED_C_TYPES_H
|
||
|
|
#include <c_Types.h>
|
||
|
|
#endif /*INCLUDED_C_TYPES_H*/
|
||
|
|
|
||
|
|
|
||
|
|
#ifndef INCLUDED_C_MEMORY_H
|
||
|
|
#include <c_Memory.h>
|
||
|
|
#endif /*INCLUDED_C_MEMORY_H*/
|
||
|
|
|
||
|
|
|
||
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
||
|
|
/* */
|
||
|
|
|
||
|
|
void c_MergeSortSub(char* arr, c_size_t left, c_size_t right, c_size_t size, char* aux,
|
||
|
|
int (*compar)(const void*, const void*));
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Top-Level Custom Framework Entry Point for Top-Down Merge Sort.
|
||
|
|
* Time Complexity: O(n log n) | Space Complexity: O(n) | Stable: Yes
|
||
|
|
*/
|
||
|
|
C_STATIC_FORCE_INLINE
|
||
|
|
void c_MergeSort(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;
|
||
|
|
c_size_t total_bytes = num * size;
|
||
|
|
|
||
|
|
// Optimization: Fallback to stack buffer allocation if overall payload fits locally
|
||
|
|
#define MERGE_STACK_LIMIT 512
|
||
|
|
char stack_buf[MERGE_STACK_LIMIT];
|
||
|
|
char* aux = NULL;
|
||
|
|
|
||
|
|
if (total_bytes <= MERGE_STACK_LIMIT) {
|
||
|
|
aux = stack_buf;
|
||
|
|
} else {
|
||
|
|
aux = (char*)C_ALLOC(total_bytes);
|
||
|
|
if (aux == NULL) return; // Allocation safeguard
|
||
|
|
}
|
||
|
|
|
||
|
|
// Execute recursive divide-and-conquer strategy
|
||
|
|
c_MergeSortSub(arr, 0, num - 1, size, aux, compar);
|
||
|
|
|
||
|
|
if (total_bytes > MERGE_STACK_LIMIT) {
|
||
|
|
C_FREE(aux);
|
||
|
|
}
|
||
|
|
#undef MERGE_STACK_LIMIT
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
#endif /*INCLUDED_C_MERGESORT_H*/
|