开始设计
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
#ifndef INCLUDED_C_SHELLSORT_H
|
||||
#define INCLUDED_C_SHELLSORT_H
|
||||
|
||||
#ifndef INCLUDED_C_BASE_H
|
||||
#include <c_Base.h>
|
||||
#endif /*INCLUDED_C_BASE_H*/
|
||||
|
||||
#ifndef INCLUDED_C_MEMORY_H
|
||||
#include <c_Memory.h>
|
||||
#endif /*INCLUDED_C_MEMORY_H*/
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
C_STATIC_FORCE_INLINE
|
||||
void c_ShellSort(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;
|
||||
|
||||
// Stack optimization for memory swap space
|
||||
#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;
|
||||
}
|
||||
|
||||
// Using Knuth's gap sequence: h = h * 3 + 1 (1, 4, 13, 40, 121, ...)
|
||||
c_size_t gap = 1;
|
||||
while (gap < num / 3) {
|
||||
gap = gap * 3 + 1;
|
||||
}
|
||||
|
||||
// Start with the largest gap and work down to a gap of 1
|
||||
while (gap > 0) {
|
||||
for (c_size_t i = gap; i < num; i++) {
|
||||
// temp = arr[i]
|
||||
memcpy(temp, arr + (i * size), size);
|
||||
|
||||
c_size_t j = i;
|
||||
|
||||
// Shift elements of the gap-sorted variant until the correct position is found
|
||||
// Loop guards prevent underflow on unsigned c_size_t subtraction (j >= gap)
|
||||
while (j >= gap && compar(arr + ((j - gap) * size), temp) > 0) {
|
||||
// arr[j] = arr[j - gap]
|
||||
memcpy(arr + (j * size), arr + ((j - gap) * size), size);
|
||||
j -= gap;
|
||||
}
|
||||
|
||||
// arr[j] = temp
|
||||
memcpy(arr + (j * size), temp, size);
|
||||
}
|
||||
// Reduce the gap
|
||||
gap /= 3;
|
||||
}
|
||||
|
||||
if (size > STACK_LIMIT) {
|
||||
C_FREE(temp);
|
||||
}
|
||||
#undef STACK_LIMIT
|
||||
}
|
||||
|
||||
|
||||
#endif /*INCLUDED_C_SHELLSORT_H*/
|
||||
Reference in New Issue
Block a user