首页 > 代码库 > bsearch

bsearch

 

C语言中 bsearch 包含在<stdlib.h>头文件中,此函数可以根据你给的条件实现二分查找,如果找到元素则返回指向该元素的指针,否则返回NULL;对于有多个元素匹配成功的情况,bsearch()未定义返回哪一个。使用 bsearch 函数也要自己定义比较子函数。

函数原型

void *bsearch(const void *key, const void *base, size_t num, size_t size, int (*cmp)(const void *,const void *));

解释一下参数

key 指向要查找的元素

base 指向进行查找的数组

num 数组中元素的个数

size 数组中每个元素的大小,一般用sizeof()表示

cmp 比较两个元素的函数,定义比较规则。需要注意的是,查找数组必须是经过预先排序的,而排序的规则要和比较子函数cmp的规则相同。

因为使用bsearch函数要求数组预先排好序,所以该函数通常和快速排序函数(qsort)一起使用,关于qsort函数,详见《C语言标准库函数 qsort 详解

关于bsearch()的具体应用请见《POJ 2503 Babelfish C语言版

 

 

 
void *bsearch (const void *key, //查找项    const void *base,     //元素数组的起始地址    size_t nmemb,         //元素的个数    size_t size,          //每个元素的长度(大小)     int (*compar) (const void *, const void *)) //比较两个元素的大小的函数{  size_t l, u, idx;  const void *p;  int comparison;  l = 0;  u = nmemb;  while (l < u)    {      idx = (l + u) / 2;    //找出中间点的偏移量,注意(l+u)      p = (void *) (((const char *) base) + (idx * size)); //找到中间点      comparison = (*compar) (key, p); //获得中间元素和关键字key之间的额比较值      if (comparison < 0)              //key小于中间值,落在左边区间,无需移动元素数组的起始地址          u = idx;                    //只要修改区间长度      else if (comparison > 0)          l = idx + 1;                //修改数组元素的起始位置,构成一个新的数组      else          return (void *) p;    }  return NULL;}

  

void* Bsearch(void* base, int len, int size, const void* key, int (*cmp)(const void* a, const void* b)){    assert(base != NULL && len >= 0 && size >= 1 && cmp != NULL);    int low = 0;    int high = len - 1;     while (low <= high) {        int mid = low + (high - low) / 2;        char* pmid = (char*)base + mid * size;        if (cmp(pmid, key) < 0) {            low = mid + 1;        } else if (cmp(pmid, key) > 0) {            high = mid - 1;        } else {            return pmid;        }    }    return NULL;}

  

 
 
 
 
 
 
 
 
 
C语言中可以用bsearch()实现二分查找。同qsort()一样,bsearch()也包含在<stdlib.h>库中,且同样要自定义比较子函数。其原型如下:
 

void *bsearch(const void *key, const void *base, size_t nmem, size_t size, int (*comp)(constvoid *, const void *));

key指向所要查找的元素,base指向进行查找的数组,nmem为查找长度,一般为数组长度,size为每个元素所占的字节数,一般用sizeof(...)表示,comp指向比较子函数,它定义比较的规则。需要注意的是,数据必须是经过预先排序的,而排序的规则要和comp所指向比较子函数的规则相同。如果查找成功则返回数组中匹配元素的地址,反之则返回空。对于有多于一个的元素匹配成功的情况,bsearch()未定义返回哪一个。

例:

 

 

 

一、对int类型数组排序int num[100];int cmp ( const void *a , const void *b ){return *(int *)a - *(int *)b;}qsort(num,100,sizeof(num[0]),cmp);二、对char类型数组排序(同int类型)char word[100];int cmp( const void *a , const void *b ){return *(char *)a - *(int *)b;}qsort(word,100,sizeof(word[0]),cmp);三、对double类型数组排序double in[100];int cmp( const void *a , const void *b ){return *(double *)a > *(double *)b ? 1 : -1;}qsort(in,100,sizeof(in[0]),cmp);四、对结构体一级排序struct Sample{double data;int other;}s[100]//按照data的值从小到大将结构体排序int cmp( const void *a ,const void *b){return (*(Sample *)a).data > (*(Sample *)b).data ? 1 : -1;}qsort(s,100,sizeof(s[0]),cmp);五、对结构体二级排序struct Sample{int x;int y;}s[100];//按照x从小到大排序,当x相等时按照y从大到小排序int cmp( const void *a , const void *b ){struct Sample *c = (Sample *)a;struct Sample *d = (Sample *)b;if(c->x != d->x) return c->x - d->x;else return d->y - c->y;}qsort(s,100,sizeof(s[0]),cmp);六、对字符串进行排序struct Sample{int data;char str[100];}s[100];//按照结构体中字符串str的字典顺序排序int cmp ( const void *a , const void *b ){return strcmp( (*(Sample *)a).str , (*(Sample *)b).str );}qsort(s,100,sizeof(s[0]),cmp);附加一个完整点的代码,对字符串二维数组排序:#include <stdio.h>#include <stdlib.h>#include <string.h>char s[2001][1001];int cmp(const void *a, const void *b){return strcmp((char *)a,(char *)b);}int main(){int i,n;scanf("%d",&n);getchar();for(i=0;i<n;i++) gets(s[i]);qsort(s,n,1001*sizeof(char),cmp);for(i=0;i<n;i++) puts(s[i]);return 0;}

  

 

 

 
 

#include <stdio.h>
#include <stdlib.h>

#define NUM 8

int compare(const void *p, const void *q)
{
    return (*(int *)p - *(int *)q);
}

int main(int argc, char *argv[])
{
    int array[NUM] = {9, 2, 7, 11, 3, 87, 34, 6};
    int key = 3;
    int *p;

    
    qsort(array, NUM, sizeof(int), compare);
    p = (int *)bsearch(&key, array, NUM, sizeof(int), compare);

    (p == NULL) ? puts("not found") : puts("found");

    return 0;
}

bsearch