在java中为了避免 low+high溢出,可以用无符号右移:正数高位补0,负数高位补1

int mid = (low + high) >>> 1;

如果是在c++中,那么需要先转换为unsigned的再移位

int a=100;
int b;
b=((unsigned int)a)>>1;

或者 int mid = low + ((high - low) / 2);

public static int binarySearch(int[] a, int target) {
int low = 0;
int high = a.length - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
int midVal = a[mid];
if (midVal < target)
low = mid + 1;
else if (midVal > target)
high = mid - 1;
else
return mid;
}
return -1;
}

  

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的更多相关文章

  1. C 语言中用bsearch()实现查找操作

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

  2. 模板:qsort+bsearch应用

    (1)qsort: 功 能: 使用快速排序例程进行排序 头文件:stdlib.h 用 法: void qsort(void *base,int nelem,int width,int (*fcmp)( ...

  3. 深入理解CPP与C中bsearch函数的用法

    ·使用besearch函数的前提(一些废话) 首先让我们先亮出二分法的定义: https://baike.baidu.com/item/二分法/1364267 以及二分法实现的方法: https:// ...

  4. sort(排序) qsort(快排) bsearch(二分查找)

    sort: 一.对int类型数组排序 int a[100]; int cmp ( int a , int b ) //不必强制转换 { return a < b;//升序排列. } sort ( ...

  5. minix中二分查找bsearch的实现

    在看minix中bsearch实现的源代码之前,先学习一下C 语言中void类型以及void*类型的使用方法与技巧. void的含义: void的字面意思是“无类型”,void *则为“无类型指针”, ...

  6. 数据结构及算法篇bsearch crypt lfind lsearch qsort rand srand

    crypt(将密码或数据编码) 相关函数 getpass 表头文件 #define _XOPEN_SOURCE #include<unistd.h> 定义函数 char * crypt ( ...

  7. qsort()和bsearch()

    qsort void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*)); Sort ...

  8. stdlib.h中自带的两个算法qsort,bsearch

    http://zh.cppreference.com/w/c/algorithm ========== void qsort( void *ptr, size_t count, size_t size ...

  9. C语言标准库 qsort bsearch 源码实现

    C语言是简洁的强大的,当然也有很多坑.C语言也是有点业界良心的,至少它实现了2个最最常用的算法:快速排序和二分查找. 我们知道,对于C语言标准库 qsort和 bsearch: a. 它是“泛型”的, ...

随机推荐

  1. 基于HTML5技术的电力3D监控应用(三)

    继(一)和(二)之后不少,不少网友问我移动终端的使用问题,因为我们项目这次采用Android平板终端,所以我对这方面有点肤浅的研究,这篇分享些项目经验总结,希望对大家有所帮助. 电力3D项目去年底刚立 ...

  2. Java魔法堂:自定义和解析注解

    一.前言 注解(Annotation)作为元数据的载体,为程序代码本身提供额外的信息,使用过MyBatis等ORM框架的朋友对 @Insert 的注解应该不陌生了,这是MyBatis自定义的注解,显然 ...

  3. .NET中的枚举(Enum)

    摘要:.NET中的枚举分为简单枚举和标志枚举,这次主要总结一下标志枚举适用条件,以及它的使用方法,并在文章的最后列举枚举使用的一些规范. 在刚接触.NET的枚举时,只用简单的枚举,对于标记枚举,只知道 ...

  4. SpringMVC基础——一个简单的例子

    一.导入 jar 包 二.配置 web.xml 文件 <servlet> <servlet-name>dispatcherServlet</servlet-name> ...

  5. 点餐系统web版功能需求

                餐厅到店点餐系统需求分析 (版本v1.0.0)               成文信息 主题词: 需求分析 作  者: 14商软ETC 文档类别: 审  核: 批  准: 文档性 ...

  6. 环信SDK与Apple Watch的结合(2)

    这一篇主要是介绍怎么拖apple watch上的相关页面,附源码EMWatchOCDemo. 需要在工程中的“EMWatchOCDemo WatchKit App”中进行操作,该文件夹的结构如图 Wa ...

  7. 【转载】JS获取屏幕大小

    前些日子需要给项目的弹窗上面罩,因为项目左侧是树形菜单,右侧嵌套的iframe ,iframe 的内容不是固定大小,那么,面罩的大小也就不是固定的 因此,用到了JQuery获取当前页面的窗口大小,于是 ...

  8. 使用Dhcpstarv解决DHCP服务器冲突问题

    场景: 内网环境需要开启多个DHCP服务器,分别给不同的设备进行PXE安装. 存在的问题: 多个DHCP的情况下,设备在启动时随机从一个DHCP服务器获取IP(哪个DHCP服务器先响应就从哪个获取)并 ...

  9. edittext 监听内容变化

    给EditText追加ChangedListener可以监听EditText内容变化的监听 如图是效果图  类似于过滤的一种实现 1  布局也就是一个EditText,当EditText内容发生变化时 ...

  10. 批量导数据之利器-load data[2016-07-11]

    由于天热,中午吃完饭后不再去逛了,感觉这段时间其实也是可以利用起来的,所以决定每天中午积累一些小的知识点.今天中午,先总结一下最近造数据用到手命令,load data. 使用这个命令的起源是因为最近要 ...