Files
cAI/cKit/Sort/c_InsertionSort.h
T

69 lines
2.0 KiB
C
Raw Normal View History

2026-08-10 01:21:15 +08:00
#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*/