你真的会二分查找么?

二分查找指的是折半查找,它最大的有点是查找过程中需要比较的次数很少,查找速度很快,其缺点是要求待查找数据为有序表,且插入删除困难。因此它适用于不经常变动但是需要频繁查找的有序表。

可以按照以下方式来实现二分查找:

1.假设待查找表的升序的

2.首先查找表中间位置记录的关键字,与查找关键字比较,若是相等,则查找成功,若是不等,则利用中间位置将表拆分成前、后两个表

3.若是中间位置记录大于查找关键字,则在浅表中再次进行二分查找,若是中间位置记录小于查找关键字,则在后表总再次进行二分查找

4.重复以上过程,知道找到满足条件的记录,即为查找成功,若是一直到子表不存在,则查找结束,此时查找不成功。


具体实现方式有两种,递归(效率不高)、非递归。

递归

int binarySearch(int data[],int begin,int end,int key){
	int result=-1;
	if(begin>end)
		return -1;
	int middle=begin+(end-begin)/2;//取中间记录位置,此处这样写可避免溢出,若是直接(begin+end)/2,可能begin及end过大时会有溢出
	if(data[middle]==key)
		result = middle;//若是中间元素等于查找关键字,则将结果值设置为中间位置
	else if(data[middle]>key)
		result = binarySearch(data,begin,middle-1,key);//若是查找关键字小于中间记录,则在左子表再进行查找
	else if(data[middle]<key)
		result = binarySearch(data,middle+1,end,key);//若是查找关键字大于中间记录,则在右子表再进行查找
	return result;
}

非递归

int binarySearch2te(int data[],int begin,int end,int key){
	int left=begin;
	int right=end;
	int middle=0;
	int result=-1;
	while(left<=right){
		middle=left+(right-left)/2;//取中间记录位置,此处这样写可避免溢出,若是直接(begin+end)/2,可能begin及end过大时会有溢出
		if(key==data[middle]){
			result = middle;//查找到关键字,则中断while循环,并将下标赋值给result
			break;
		}
		else if(key<data[middle])//如果查找关键字小于中间记录,则将查找范围设置为左子表(查找区间为begin,middle-1)
			right=middle-1;
		else if(key>data[middle])//如果查找关键字大于中间记录,则将查找范围设置为右子表(查找区间为middle+1,right)
			left=middle+1;
	}
	return result;
}

程序主入口

int _tmain(int argc, _TCHAR* argv[])
{
	int data[] = {1,2,3,5,7};
	int length = sizeof(data)/sizeof(data[0]);//计算数组长度
	int key=2;
	int position=binarySearch(data,0,length,key);
	if(position!=-1)
		cout<<"find the key("<<key<<"),position is:"<<position<<",value is:"<<data[position]<<endl;
	else
		cout<<"could not find the key in data."<<endl;
	int position2=binarySearch2te(data,0,length,key);
	if(position2!=-1)
		cout<<"find the key("<<key<<"),position is:"<<position2<<",value is:"<<data[position2]<<endl;
	else
		cout<<"could not find the key in data."<<endl;
	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值