69 lines
2.0 KiB
C
69 lines
2.0 KiB
C
#ifndef INCLUDED_C_INSERTIONSORT_H
|
|
#define INCLUDED_C_INSERTIONSORT_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*/
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
/* */
|
|
|
|
|
|
/**
|
|
* 通用插入排序函数
|
|
* @param base 指向待排序数组首元素的指针
|
|
* @param num 数组中元素的个数
|
|
* @param size 每个元素的大小(字节数)
|
|
* @param compar 指向比较函数的指针
|
|
*/
|
|
C_STATIC_FORCE_INLINE
|
|
void c_InsertionSort(void* base, c_size_t num, c_size_t size,
|
|
int (*compar)(const void*, const void*)) {
|
|
char* arr = (char*)base; // 强转为 char* 以便按单字节进行指针偏移
|
|
|
|
// 分配一块临时内存,用于存放当前要插入的“哨兵”元素(temp)
|
|
#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 = 1; i < num; i++) {
|
|
// temp = arr[i]:将当前元素复制到临时空间
|
|
memcpy(temp, arr + (i * size), size);
|
|
|
|
long long j = i - 1;
|
|
|
|
// 循环条件:j >= 0 且 arr[j] > temp
|
|
// 使用 compar(arr + (j * size), temp) > 0 来判断是否需要后移
|
|
while (j >= 0 && compar(arr + (j * size), temp) > 0) {
|
|
// arr[j + 1] = arr[j]:将前面的元素往后移一位
|
|
memcpy(arr + ((j + 1) * size), arr + (j * size), size);
|
|
j--;
|
|
}
|
|
|
|
// arr[j + 1] = temp:将目标元素插入到正确位置
|
|
memcpy(arr + ((j + 1) * 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_INSERTIONSORT_H*/
|