68 lines
1.9 KiB
C
68 lines
1.9 KiB
C
#ifndef INCLUDED_C_SELECTIONSORT_H
|
|
#define INCLUDED_C_SELECTIONSORT_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*/
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
/* */
|
|
|
|
/**
|
|
* Generic Selection Sort Function
|
|
* @param base Pointer to the first element of the array to be sorted
|
|
* @param num Number of elements in the array
|
|
* @param size Size of each element in bytes
|
|
* @param compar Pointer to the comparison function
|
|
*/
|
|
C_STATIC_FORCE_INLINE
|
|
void c_SelectionSort(void* base, c_size_t num, c_size_t size,
|
|
int (*compar)(const void*, const void*)) {
|
|
// Avoid execution if array is empty or has only one element
|
|
if (base == NULL || num < 2 || size == 0) return;
|
|
|
|
char* arr = (char*)base;
|
|
|
|
// OPTIMIZATION: Use stack allocation for small element sizes
|
|
// to bypass heap overhead completely during force-inlining.
|
|
#define STACK_LIMIT 128
|
|
char stack_buf[STACK_LIMIT];
|
|
void* temp = NULL;
|
|
|
|
if (size <= STACK_LIMIT) {
|
|
temp = stack_buf;
|
|
} else {
|
|
temp = C_ALLOC(size);
|
|
if (temp == NULL) return;
|
|
}
|
|
|
|
for (c_size_t i = 0; i < num - 1; i++) {
|
|
c_size_t minIndex = i;
|
|
|
|
for (c_size_t j = i + 1; j < num; j++) {
|
|
if (compar(arr + (j * size), arr + (minIndex * size)) < 0) {
|
|
minIndex = j;
|
|
}
|
|
}
|
|
|
|
if (minIndex != i) {
|
|
memcpy(temp, arr + (i * size), size);
|
|
memcpy(arr + (i * size), arr + (minIndex * size), size);
|
|
memcpy(arr + (minIndex * size), temp, size);
|
|
}
|
|
}
|
|
|
|
// Only trigger free if it was actually allocated from the heap
|
|
if (size > STACK_LIMIT) {
|
|
C_FREE(temp);
|
|
}
|
|
#undef STACK_LIMIT
|
|
}
|
|
|
|
#endif /*INCLUDED_C_SELECTIONSORT_H*/
|