bsearch
在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 函数也要自己定义比较子函数。
函数原型
解释一下参数
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;
}
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> #define NUM 8 int compare(const void *p, const void *q) int main(int argc, char *argv[]) qsort(array, NUM, sizeof(int), compare); (p == NULL) ? puts("not found") : puts("found"); return 0; |
bsearch的更多相关文章
- C 语言中用bsearch()实现查找操作
C语言中可以用bsearch()实现二分查找.同qsort()一样,bsearch()也包含在库中,且同样要自定义比较子函数.其原型如下: void *bsearch(const void *key, ...
- 模板:qsort+bsearch应用
(1)qsort: 功 能: 使用快速排序例程进行排序 头文件:stdlib.h 用 法: void qsort(void *base,int nelem,int width,int (*fcmp)( ...
- 深入理解CPP与C中bsearch函数的用法
·使用besearch函数的前提(一些废话) 首先让我们先亮出二分法的定义: https://baike.baidu.com/item/二分法/1364267 以及二分法实现的方法: https:// ...
- sort(排序) qsort(快排) bsearch(二分查找)
sort: 一.对int类型数组排序 int a[100]; int cmp ( int a , int b ) //不必强制转换 { return a < b;//升序排列. } sort ( ...
- minix中二分查找bsearch的实现
在看minix中bsearch实现的源代码之前,先学习一下C 语言中void类型以及void*类型的使用方法与技巧. void的含义: void的字面意思是“无类型”,void *则为“无类型指针”, ...
- 数据结构及算法篇bsearch crypt lfind lsearch qsort rand srand
crypt(将密码或数据编码) 相关函数 getpass 表头文件 #define _XOPEN_SOURCE #include<unistd.h> 定义函数 char * crypt ( ...
- qsort()和bsearch()
qsort void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*)); Sort ...
- stdlib.h中自带的两个算法qsort,bsearch
http://zh.cppreference.com/w/c/algorithm ========== void qsort( void *ptr, size_t count, size_t size ...
- C语言标准库 qsort bsearch 源码实现
C语言是简洁的强大的,当然也有很多坑.C语言也是有点业界良心的,至少它实现了2个最最常用的算法:快速排序和二分查找. 我们知道,对于C语言标准库 qsort和 bsearch: a. 它是“泛型”的, ...
随机推荐
- Web 开发人员必备的随机 JSON 数据生成工具
在 Web 开发中,经常会需要一些测试数据来测试接口或者功能时候正确.JSON Generator 就是这样一款生成随机 JSON 数据的在线工具,Web 开发人员必备,记得收藏和分享啊. 您可能感兴 ...
- Teehan & Lax 发布 iOS 7 GUI PSD 模板,免费下载
在 iOS 7 发布不久,Teehan & Lax 就发布了 iOS 7 GUI PSD 模板.该网站分享众多 PSD 模板素材,这些精美的 PSD 界面模板在制作界面原型非常有用,能够帮助设 ...
- 妹味6:ajax与ajax封装
(功能)ajax能且仅能 从服务器读取文件 (环境)需要服务器环境才能测试,可以用工具建立本地服务器环境 (缓存)解决缓存问题:url加时间戳让每次请求地址唯一,如 url='abc.txt?t='+ ...
- 说说Web API数据格式化——Json
题外话 一同事离职了,我去上厕所的路上正巧碰到他办完离职手续出来,抱着他的全部家当,最值钱的可能就是那个两块钱的蓝色杯子和手中的雨伞了.在一块儿走向厕所的长长楼道里,我对他说:丫的,你是不是找到别的发 ...
- UWP开发入门(十二)——神器Live Visual Tree
很久以前,我们就有Snoop这样的工具实时修改.查看正在运行的WPF程序,那时候调个样式,修改个模板,相当滋润.随着历史的车轮陷进WP的泥潭中,无论WP7的Silverlight还是WP8.1的run ...
- 如何单独启动wamp 中自带的MySQL
前言:Wamp集成了Apache.MySQL和PHP环境.使用Wamp进行网站开发,是很多网站开发爱好者的选择.同时,其集成的MySQL服务,也常被用于MySQL的开发.这个时候我们只是想启动MySQ ...
- ASP.NET 运行时详解 揭开请求过程神秘面纱
对于ASP.NET开发,排在前五的话题离不开请求生命周期.像什么Cache.身份认证.Role管理.Routing映射,微软到底在请求过程中干了哪些隐秘的事,现在是时候揭晓了.抛开乌云见晴天,接下来就 ...
- .net接口学习笔记
1.接口的声明 接口的声明不能包含:数据成员,静态变量:只能包含如下类型的静态成员函数的声明:方法,属性,事件,索引器.声明中不能包含任何实现的代码,而在每个成员成名的主体后,必须使用分号. 接口声明 ...
- 怎样从C#中打开数据库并进行 增 删 改 查 操作
首先 在C#中引用数据库的操作! (因为我们用的是SQLserver数据库,所以是SqlClient) using System.Data.SqlClient; 1:要实现对数据库的操作,我们必须先登 ...
- 取值:webconfig中的key
String rootUrl = System.Configuration.ConfigurationManager.AppSettings["SiteDomain"].ToStr ...