查找一个范围的二分查找
说白了就是分两次查找,一次查找(>=)的边界,一次查找(<=)的边界:
/************************************************************************/
/* Function:扩展的二分查找,在已经排好序的数据集中进行查找
/* Input :
key1 指向void类型数据的常指针类型 要查找的对象(作为一个边界)
key2 指向void类型数据的常指针类型 要查找的对象(作为另一个边界)
base 指向void类型数据的常指针类型 要从中查找出目的数据的数据集起始点
num size_t类型 元素个数
width size_t 每个元素占用的字节个数
result 指向 指向void类型数据的指针 的指针 符合要求的数据的起始位置
/* Return :int 类型 符合要求的元素数量
/* Time :2008-10-08
/************************************************************************/
int bsearch_range(const void *key1,
const void *key2,
const void *base,
size_t num,
size_t width,
int(*compare)(const void *, const void *),
void **result
)
{
int a = 0, b = num - 1, c1 = num / 2, c2 = num / 2;
while(a <= b)
{
int r = compare(key1, (char*)base + c1 * width);
if( r <= 0 ) b = c1 - 1;
else a = c1 + 1;
c1 = (a + b + 1) / 2;
}
a = 0, b = num - 1;
while(a <= b)
{
int r = compare(key2, (char*)base + c2 * width);
if( r < 0 ) b = c2 - 1;
else a = c2 + 1;
c2 = (a + b + 1) / 2;
}
if(result) *result = (char*)base + c1 * width;
return c2 - c1;
}
/* Function:扩展的二分查找,在已经排好序的数据集中进行查找
/* Input :
key1 指向void类型数据的常指针类型 要查找的对象(作为一个边界)
key2 指向void类型数据的常指针类型 要查找的对象(作为另一个边界)
base 指向void类型数据的常指针类型 要从中查找出目的数据的数据集起始点
num size_t类型 元素个数
width size_t 每个元素占用的字节个数
result 指向 指向void类型数据的指针 的指针 符合要求的数据的起始位置
/* Return :int 类型 符合要求的元素数量
/* Time :2008-10-08
/************************************************************************/
int bsearch_range(const void *key1,
const void *key2,
const void *base,
size_t num,
size_t width,
int(*compare)(const void *, const void *),
void **result
)
{
int a = 0, b = num - 1, c1 = num / 2, c2 = num / 2;
while(a <= b)
{
int r = compare(key1, (char*)base + c1 * width);
if( r <= 0 ) b = c1 - 1;
else a = c1 + 1;
c1 = (a + b + 1) / 2;
}
a = 0, b = num - 1;
while(a <= b)
{
int r = compare(key2, (char*)base + c2 * width);
if( r < 0 ) b = c2 - 1;
else a = c2 + 1;
c2 = (a + b + 1) / 2;
}
if(result) *result = (char*)base + c1 * width;
return c2 - c1;
}