|
@@ -2,16 +2,19 @@
|
|
|
#include <string.h>
|
|
#include <string.h>
|
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
-static void merge(char* a_begin,
|
|
|
|
|
|
|
+static bool merge(char* a_begin,
|
|
|
char* a_end,
|
|
char* a_end,
|
|
|
char* b_begin,
|
|
char* b_begin,
|
|
|
char* b_end,
|
|
char* b_end,
|
|
|
char* res,
|
|
char* res,
|
|
|
int elem_size,
|
|
int elem_size,
|
|
|
- int (*cmp)(const void* a, const void* b)) {
|
|
|
|
|
|
|
+ int (*f_le)(const void* a, const void* b)) {
|
|
|
char *a = a_begin, *b = b_begin, *r = res;
|
|
char *a = a_begin, *b = b_begin, *r = res;
|
|
|
while(a < a_end && b < b_end) {
|
|
while(a < a_end && b < b_end) {
|
|
|
- if(cmp(a, b) <= 0) {
|
|
|
|
|
|
|
+ int res = f_le(a, b);
|
|
|
|
|
+ // check error
|
|
|
|
|
+ if(res == -1) return false;
|
|
|
|
|
+ if(res) {
|
|
|
memcpy(r, a, elem_size);
|
|
memcpy(r, a, elem_size);
|
|
|
a += elem_size;
|
|
a += elem_size;
|
|
|
} else {
|
|
} else {
|
|
@@ -26,22 +29,27 @@ static void merge(char* a_begin,
|
|
|
memcpy(r, a, elem_size);
|
|
memcpy(r, a, elem_size);
|
|
|
for(; b < b_end; b += elem_size, r += elem_size)
|
|
for(; b < b_end; b += elem_size, r += elem_size)
|
|
|
memcpy(r, b, elem_size);
|
|
memcpy(r, b, elem_size);
|
|
|
|
|
+ return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void c11__stable_sort(void* ptr_,
|
|
|
|
|
|
|
+bool c11__stable_sort(void* ptr_,
|
|
|
int count,
|
|
int count,
|
|
|
int elem_size,
|
|
int elem_size,
|
|
|
- int (*cmp)(const void* a, const void* b)) {
|
|
|
|
|
|
|
+ int (*f_le)(const void* a, const void* b)) {
|
|
|
// merge sort
|
|
// merge sort
|
|
|
- char* ptr = ptr_, *tmp = malloc(count * elem_size);
|
|
|
|
|
|
|
+ char *ptr = ptr_, *tmp = malloc(count * elem_size);
|
|
|
for(int seg = 1; seg < count; seg *= 2) {
|
|
for(int seg = 1; seg < count; seg *= 2) {
|
|
|
for(char* a = ptr; a < ptr + (count - seg) * elem_size; a += 2 * seg * elem_size) {
|
|
for(char* a = ptr; a < ptr + (count - seg) * elem_size; a += 2 * seg * elem_size) {
|
|
|
- char* 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);
|
|
|
|
|
|
|
+ char *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;
|
|
|
|
|
+ bool ok = merge(a, a_end, b, b_end, tmp, elem_size, f_le);
|
|
|
|
|
+ if(!ok) {
|
|
|
|
|
+ free(tmp);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ memcpy(a, tmp, b_end - a);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- free(tmp);
|
|
|
|
|
|
|
+ free(tmp);
|
|
|
|
|
+ return true;
|
|
|
}
|
|
}
|