重构
This commit is contained in:
@@ -1,79 +0,0 @@
|
||||
#ifndef INCLUDED_C_BINARYINSERTIONSORT_H
|
||||
#define INCLUDED_C_BINARYINSERTIONSORT_H
|
||||
|
||||
#ifndef INCLUDED_C_TYPES_H
|
||||
#include <c_Types.h>
|
||||
#endif /*INCLUDED_C_TYPES_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_BinaryInsertionSort(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);
|
||||
|
||||
// 1. 使用二分查找决定插入位置 [left, right]
|
||||
long long left = 0;
|
||||
long long right = i - 1;
|
||||
|
||||
while (left <= right) {
|
||||
long long mid = left + (right - left) / 2;
|
||||
|
||||
// 为了保证排序的稳定性(Stability),
|
||||
// 当 mid 元素等于 temp 时,应当继续向右区间查找,把 temp 放到相同元素的后面
|
||||
if (compar(arr + (mid * size), temp) <= 0) {
|
||||
left = mid + 1; // 目标位置在右边
|
||||
} else {
|
||||
right = mid - 1; // 目标位置在左边
|
||||
}
|
||||
}
|
||||
// 循环结束时,left 就是元素应该插入的目标索引位置
|
||||
|
||||
// 2. 将 [left, i-1] 区间的元素全部向后移动一个位置
|
||||
for (long long j = i - 1; j >= left; j--) {
|
||||
memcpy(arr + ((j + 1) * size), arr + (j * size), size);
|
||||
}
|
||||
|
||||
// 3. 将 temp 插入到腾出来的 left 位置
|
||||
memcpy(arr + (left * 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_BINARYINSERTIONSORT_H*/
|
||||
Reference in New Issue
Block a user