Change sort function name

This commit is contained in:
jun 2025-01-30 14:07:08 +01:00
parent 8c324c00f7
commit 67b5759e03
3 changed files with 35 additions and 21 deletions

View File

@ -11,8 +11,8 @@ typedef enum guf_sort_opt {
#ifdef GUF_T
#ifndef GUF_T_NAME
#define GUF_T_NAME GUF_T
#ifndef GUF_FN_NAME_PREFIX
#define GUF_FN_NAME_PREFIX GUF_CAT(GUF_T, _arr)
#endif
#ifdef GUF_IMPL_STATIC
@ -21,9 +21,11 @@ typedef enum guf_sort_opt {
#define GUF_FN_KEYWORDS
#endif
GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_T_NAME, _insertion_sort)(GUF_T *arr, ptrdiff_t n, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b));
GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_T_NAME, _merge_sort)(GUF_T *restrict arr, GUF_T *restrict arr_tmp, ptrdiff_t n, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b));
GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_T_NAME, _qsort)(GUF_T *arr, ptrdiff_t n, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b));
GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_FN_NAME_PREFIX, _insertion_sort)(GUF_T *arr, ptrdiff_t n, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b));
GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_FN_NAME_PREFIX, _merge_sort)(GUF_T *restrict arr, GUF_T *restrict arr_tmp, ptrdiff_t n, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b));
GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_FN_NAME_PREFIX, _qsort)(GUF_T *arr, ptrdiff_t n, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b));
GUF_FN_KEYWORDS bool GUF_CAT(GUF_FN_NAME_PREFIX, _is_sorted)(GUF_T *arr, ptrdiff_t n, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b));
#if defined(GUF_IMPL) || defined(GUF_IMPL_STATIC)
@ -36,7 +38,7 @@ GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_T_NAME, _qsort)(GUF_T *arr, ptrdiff_t n, guf_
- time: worst O(n^2); average O(n^2); best O(n) (if arr is already sorted)
- space: O(1)
*/
GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_T_NAME, _insertion_sort)(GUF_T *arr, ptrdiff_t n, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b))
GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_FN_NAME_PREFIX, _insertion_sort)(GUF_T *arr, ptrdiff_t n, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b))
{
GUF_ASSERT_RELEASE(arr);
GUF_ASSERT_RELEASE(n >= 0);
@ -57,7 +59,7 @@ GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_T_NAME, _insertion_sort)(GUF_T *arr, ptrdiff_
- time: O(n * log n) (worst, average, and best)
- space: always O(n) (for arr_tmp, allocated and freed by the caller)
*/
GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_T_NAME, _merge_sort)(GUF_T *restrict arr, GUF_T *restrict arr_tmp, ptrdiff_t n, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b))
GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_FN_NAME_PREFIX, _merge_sort)(GUF_T *restrict arr, GUF_T *restrict arr_tmp, ptrdiff_t n, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b))
{
GUF_ASSERT_RELEASE(arr);
GUF_ASSERT_RELEASE(n >= 0);
@ -98,7 +100,7 @@ GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_T_NAME, _merge_sort)(GUF_T *restrict arr, GUF
- time: worst O(n^2); average O(n * log n); best O(n * log n)
- space: worst O(log n) (stack space used for the recursive function calls)
*/
static GUF_T *GUF_CAT(GUF_T_NAME, _qsort_range)(GUF_T *arr, ptrdiff_t first_idx, ptrdiff_t last_idx, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b))
static GUF_T *GUF_CAT(GUF_FN_NAME_PREFIX, _qsort_range)(GUF_T *arr, ptrdiff_t first_idx, ptrdiff_t last_idx, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b))
{
GUF_ASSERT(arr);
GUF_ASSERT(sort_opt == GUF_SORT_ASCENDING || sort_opt == GUF_SORT_DESCENDING);
@ -138,17 +140,17 @@ static GUF_T *GUF_CAT(GUF_T_NAME, _qsort_range)(GUF_T *arr, ptrdiff_t first_idx,
(Solution to exercise "II.7.4c. Stack depth for quicksort". In "Introduction to Algorithms" (3rd ed, p. 188))
*/
if (pivot_idx <= mid_idx) { // a.) Left subarray is smaller or equal than the right subarray -> recur into the smaller left subarray first.
GUF_CAT(GUF_T_NAME, _qsort_range)(arr, first_idx, pivot_idx - 1, sort_opt, cmp);
GUF_CAT(GUF_FN_NAME_PREFIX, _qsort_range)(arr, first_idx, pivot_idx - 1, sort_opt, cmp);
first_idx = pivot_idx + 1;
} else { // b.) Right subarray is smaller than the left subarray -> recur into the smaller right subarray first.
GUF_CAT(GUF_T_NAME, _qsort_range)(arr, pivot_idx + 1, last_idx, sort_opt, cmp);
GUF_CAT(GUF_FN_NAME_PREFIX, _qsort_range)(arr, pivot_idx + 1, last_idx, sort_opt, cmp);
last_idx = pivot_idx - 1;
}
}
return arr;
}
GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_T_NAME, _qsort)(GUF_T *arr, ptrdiff_t n, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b))
GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_FN_NAME_PREFIX, _qsort)(GUF_T *arr, ptrdiff_t n, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b))
{
GUF_ASSERT_RELEASE(arr);
GUF_ASSERT_RELEASE(sort_opt == GUF_SORT_ASCENDING || sort_opt == GUF_SORT_DESCENDING);
@ -156,20 +158,31 @@ GUF_FN_KEYWORDS GUF_T *GUF_CAT(GUF_T_NAME, _qsort)(GUF_T *arr, ptrdiff_t n, guf_
if (n <= 1) {
return arr;
} else if (n <= 4) {
return GUF_CAT(GUF_T_NAME, _insertion_sort)(arr, n, sort_opt, cmp);
return GUF_CAT(GUF_FN_NAME_PREFIX, _insertion_sort)(arr, n, sort_opt, cmp);
} else {
return GUF_CAT(GUF_T_NAME, _qsort_range)(arr, 0, n - 1, sort_opt, cmp);
return GUF_CAT(GUF_FN_NAME_PREFIX, _qsort_range)(arr, 0, n - 1, sort_opt, cmp);
}
}
GUF_FN_KEYWORDS bool GUF_CAT(GUF_FN_NAME_PREFIX, _is_sorted)(GUF_T *arr, ptrdiff_t n, guf_sort_opt sort_opt, int(*cmp)(const GUF_T *a, const GUF_T *b))
{
GUF_ASSERT_RELEASE(arr);
for (ptrdiff_t i = 0; i < n - 1; ++i) {
if (!guf_before_or_equal(arr + i, arr + (i+1))) {
return false;
}
}
return true;
}
#undef guf_before
#undef guf_before_or_equal
#endif /* end #ifdef GUF_IMPL */
#undef GUF_T
#undef GUF_T_NAME
#endif /* end #ifdef GUF_T */
#undef GUF_IMPL
#undef GUF_IMPL_STATIC
#undef GUF_FN_KEYWORDS
#endif /* end #ifdef GUF_IMPL */
#undef GUF_T
#undef GUF_FN_NAME_PREFIX
#endif /* end #ifdef GUF_T */

View File

@ -53,11 +53,12 @@ int main(void)
}
// float *tmp = test_allocator.alloc(floats.size * sizeof(float), &test_allocator_ctx);
// float *res = float_merge_sort(floats.data, tmp, floats.size, GUF_SORT_ASCENDING, NULL);
// float *res = float_arr_merge_sort(floats.data, tmp, floats.size, GUF_SORT_ASCENDING, NULL);
// test_allocator.free(tmp, floats.size * sizeof(float), &test_allocator_ctx);
// GUF_ASSERT_RELEASE(res == floats.data);
float_qsort(floats.data, floats.size, GUF_SORT_ASCENDING, NULL);
float_arr_qsort(floats.data, floats.size, GUF_SORT_ASCENDING, NULL);
GUF_ASSERT_RELEASE(float_arr_is_sorted(floats.data, floats.size, GUF_SORT_ASCENDING, NULL));
GUF_CNT_FOREACH(&floats, dbuf_float, it) {
printf("float: %f\n", (double)*it.ptr);

View File

@ -1,7 +1,7 @@
#ifndef GUF_UTILS_H
#define GUF_UTILS_H
static inline bool guf_is_big_endian(void)
static inline bool guf_system_is_big_endian(void)
{
unsigned i = 1;
const char *bytes = (const char*)&i;