2002-06-21 03:51:40 +08:00
|
|
|
/*
|
|
|
|
* bsearch.c
|
|
|
|
* Original Author: G. Haley
|
|
|
|
* Rewritten by: G. Noer
|
|
|
|
*
|
|
|
|
* Searches an array of nmemb members, the initial member of which is pointed
|
|
|
|
* to by base, for a member that matches the object pointed to by key. The
|
|
|
|
* contents of the array shall be in ascending order according to a comparison
|
|
|
|
* function pointed to by compar. The function shall return an integer less
|
|
|
|
* than, equal to or greater than zero if the first argument is considered to be
|
|
|
|
* respectively less than, equal to or greater than the second. Returns a
|
|
|
|
* pointer to the matching member of the array, or a null pointer if no match
|
|
|
|
* is found.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
FUNCTION
|
|
|
|
<<bsearch>>---binary search
|
|
|
|
|
|
|
|
INDEX
|
|
|
|
bsearch
|
|
|
|
|
2017-11-30 15:41:48 +08:00
|
|
|
SYNOPSIS
|
2002-06-21 03:51:40 +08:00
|
|
|
#include <stdlib.h>
|
|
|
|
void *bsearch(const void *<[key]>, const void *<[base]>,
|
|
|
|
size_t <[nmemb]>, size_t <[size]>,
|
|
|
|
int (*<[compar]>)(const void *, const void *));
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
<<bsearch>> searches an array beginning at <[base]> for any element
|
|
|
|
that matches <[key]>, using binary search. <[nmemb]> is the element
|
|
|
|
count of the array; <[size]> is the size of each element.
|
|
|
|
|
|
|
|
The array must be sorted in ascending order with respect to the
|
|
|
|
comparison function <[compar]> (which you supply as the last argument of
|
|
|
|
<<bsearch>>).
|
|
|
|
|
|
|
|
You must define the comparison function <<(*<[compar]>)>> to have two
|
|
|
|
arguments; its result must be negative if the first argument is
|
|
|
|
less than the second, zero if the two arguments match, and
|
|
|
|
positive if the first argument is greater than the second (where
|
|
|
|
``less than'' and ``greater than'' refer to whatever arbitrary
|
|
|
|
ordering is appropriate).
|
|
|
|
|
|
|
|
RETURNS
|
|
|
|
Returns a pointer to an element of <[array]> that matches <[key]>. If
|
|
|
|
more than one matching element is available, the result may point to
|
|
|
|
any of them.
|
|
|
|
|
|
|
|
PORTABILITY
|
|
|
|
<<bsearch>> is ANSI.
|
|
|
|
|
|
|
|
No supporting OS subroutines are required.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
_PTR
|
|
|
|
_DEFUN (bsearch, (key, base, nmemb, size, compar),
|
|
|
|
_CONST _PTR key _AND
|
|
|
|
_CONST _PTR base _AND
|
|
|
|
size_t nmemb _AND
|
|
|
|
size_t size _AND
|
2009-12-18 03:43:43 +08:00
|
|
|
int _EXFNPTR(compar, (const _PTR, const _PTR)))
|
2002-06-21 03:51:40 +08:00
|
|
|
{
|
|
|
|
_PTR current;
|
|
|
|
size_t lower = 0;
|
|
|
|
size_t upper = nmemb;
|
|
|
|
size_t index;
|
|
|
|
int result;
|
|
|
|
|
|
|
|
if (nmemb == 0 || size == 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
while (lower < upper)
|
|
|
|
{
|
|
|
|
index = (lower + upper) / 2;
|
|
|
|
current = (_PTR) (((char *) base) + (index * size));
|
|
|
|
|
|
|
|
result = compar (key, current);
|
|
|
|
|
|
|
|
if (result < 0)
|
|
|
|
upper = index;
|
|
|
|
else if (result > 0)
|
|
|
|
lower = index + 1;
|
|
|
|
else
|
|
|
|
return current;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|