mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-23 21:10:19 +00:00
add stable_sort
This commit is contained in:
parent
4b2b92c1ba
commit
ac70331977
@ -25,6 +25,18 @@ extern "C" {
|
|||||||
*(out_index) = __first - (T*)(ptr); \
|
*(out_index) = __first - (T*)(ptr); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sorts an array of elements of the same type, using the given comparison function.
|
||||||
|
* @param ptr Pointer to the first element of the array.
|
||||||
|
* @param count Number of elements in the array.
|
||||||
|
* @param elem_size Size of each element in the array.
|
||||||
|
* @param cmp Comparison function that takes two elements and returns an integer similar to `strcmp`.
|
||||||
|
*/
|
||||||
|
void c11__stable_sort(void* ptr,
|
||||||
|
int count,
|
||||||
|
int elem_size,
|
||||||
|
int (*cmp)(const void* a, const void* b));
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,2 +1,47 @@
|
|||||||
#include "pocketpy/common/algorithm.h"
|
#include "pocketpy/common/algorithm.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static void merge(void* a_begin,
|
||||||
|
void* a_end,
|
||||||
|
void* b_begin,
|
||||||
|
void* b_end,
|
||||||
|
void* res,
|
||||||
|
int elem_size,
|
||||||
|
int (*cmp)(const void* a, const void* b)) {
|
||||||
|
void *a = a_begin, *b = b_begin, *r = res;
|
||||||
|
while(a < a_end && b < b_end) {
|
||||||
|
if(cmp(a, b) <= 0) {
|
||||||
|
memcpy(r, a, elem_size);
|
||||||
|
a += elem_size;
|
||||||
|
} else {
|
||||||
|
memcpy(r, b, elem_size);
|
||||||
|
b += elem_size;
|
||||||
|
}
|
||||||
|
r += elem_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// one of the arrays is empty
|
||||||
|
for(; a < a_end; a += elem_size, r += elem_size)
|
||||||
|
memcpy(r, a, elem_size);
|
||||||
|
for(; b < b_end; b += elem_size, r += elem_size)
|
||||||
|
memcpy(r, b, elem_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void c11__stable_sort(void* ptr,
|
||||||
|
int count,
|
||||||
|
int elem_size,
|
||||||
|
int (*cmp)(const void* a, const void* b)) {
|
||||||
|
// merge sort
|
||||||
|
void* tmp = malloc(count * elem_size);
|
||||||
|
for(int seg = 1; seg < count; seg *= 2) {
|
||||||
|
for(void* a = ptr; a < ptr + (count - seg) * elem_size; a += 2 * seg * elem_size) {
|
||||||
|
void* b = a + seg * elem_size, *a_end = b, *b_end = b + seg * elem_size;
|
||||||
|
if (b_end > ptr + count * elem_size)
|
||||||
|
b_end = ptr + count * elem_size;
|
||||||
|
merge(a, a_end, b, b_end, tmp, elem_size, cmp);
|
||||||
|
memcpy(a, tmp, (b_end - a) * elem_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user