二分查找指的是折半查找,它最大的有点是查找过程中需要比较的次数很少,查找速度很快,其缺点是要求待查找数据为有序表,且插入删除困难。因此它适用于不经常变动但是需要频繁查找的有序表。
可以按照以下方式来实现二分查找:
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;
}