50 lines
1.7 KiB
C
50 lines
1.7 KiB
C
#ifndef INCLUDED_C_BINARYSEARCH_H
|
|
#define INCLUDED_C_BINARYSEARCH_H
|
|
|
|
#ifndef INCLUDED_C_BASE_H
|
|
#include <c_Base.h>
|
|
#endif /*INCLUDED_C_BASE_H*/
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
/* */
|
|
|
|
/**
|
|
* 通用二分查找函数
|
|
* @param key 指向要查找的目标元素的指针
|
|
* @param base 指向待查找数组首元素的指针
|
|
* @param num 数组中元素的个数
|
|
* @param size 每个元素的大小(以字节为单位,使用 sizeof 获取)
|
|
* @param compar 指向比较函数的指针(由用户提供比较逻辑)
|
|
* @return 找到则返回指向该元素的指针,未找到则返回 NULL
|
|
*/
|
|
C_STATIC_FORCE_INLINE
|
|
void* c_BinarySearch(const void* key, const void* base, c_size_t num, c_size_t size,
|
|
int (*compar)(const void*, const void*)) {
|
|
c_size_t left = 0;
|
|
c_size_t right = num; // 使用左闭右开区间 [left, right) 逻辑更清晰
|
|
|
|
while (left < right) {
|
|
c_size_t mid = left + (right - left) / 2;
|
|
|
|
// 计算 mid 元素的内存地址:首地址 + 索引 * 每个元素的字节大小
|
|
// 先强转为 char* 是为了按单字节进行指针偏移
|
|
const void* midElem = (const char*)base + (mid * size);
|
|
|
|
// 调用用户自定义的比较函数
|
|
int cmp = compar(key, midElem);
|
|
|
|
if (cmp == 0) {
|
|
return (void*)midElem; // 找到目标,返回其在数组中的地址
|
|
} else if (cmp > 0) {
|
|
left = mid + 1; // key 大于 midElem,往右半部分找
|
|
} else {
|
|
right = mid; // key 小于 midElem,往左半部分找
|
|
}
|
|
}
|
|
|
|
return NULL; // 未找到
|
|
}
|
|
|
|
#endif /*INCLUDED_C_BINARYSEARCH_H*/
|