二分搜索 一种比较完美的实现方法

 

二分搜索,也称二分查找、折半搜索,是一种在有序数组中查找特定元素的搜索算法。搜索从数组的中间元素开始,如果中间元素刚好是要查找的元素,则搜索结束,如果要查找的特定元素大于(小于)中间元素,则在数组大于(小于)中间元素的一半中查找。该算法的递归实现比较容易理解,思路更清晰,但效率方面仍有提高的空间。


代码如下:


//递归版本
int binary_search( const int arr[], int low, int high, int key)
{
   int mid = low+(high-low)/2; // Do not use (low+high)/2 which might encounter overflow issue
   if(low>high)
       return -1;
   else
     {
       if(arr[mid]==key)
          return mid;
       else if(arr[mid]>key)
          return binary_search(arr,low,mid-1,key);
       else 
          return binary_search(arr,mid+1,high,key);
     }
}

  

需要注意的是int mid = low+(high-low)/2;而不是(low+high)/2,避免了溢出的情况。
但是当有序数组存在等值时,该方法需要根据指定的规则选取第一个(最后一个)的等值,此时只需要从mid向前(后)寻找即可。

由于寻找第一个、最后一个等值的时候,每次移动的步长为1,移动效率较低,此时可以再次使用二分查找的方法,加快寻找速度。

代码如下:

 

#include <cstdio>
//flag 1表示查找第一个等值 0查找最后一个等值  
int binarySearch(int *data, int length,int val,int flag)
{
	if(!data)return -1;
	int left,right,res;
	left = 0;
	right = length-1;
	
	res = -1;
	
	while(left<=right)
	{
		int mid = left + (right-left)/2;
		if(data[mid]==val)
		{
			res = mid;
			if(flag==0) 
			{
				right=mid-1;
			}
			else if(flag==1)
			{
				left=mid+1;
			} 
			else
				return mid;//返回索引值 
		}	
		else if(data[mid]<val)
			left=mid+1;
		else
			right= mid-1;
	}
	return res;
}


int main()
{
	int data[10]={
		4,5,23,60,60,86,88,89,89,101
	};
	printf("%d\n",binarySearch(data,10,4,1));
	
	printf("%d\n",binarySearch(data,10,60,1));
	printf("%d\n",binarySearch(data,10,60,0));
	printf("%d\n",binarySearch(data,10,55,0));
	printf("%d\n",binarySearch(data,10,89,0));
	printf("%d\n",binarySearch(data,10,89,1));
	printf("%d\n",binarySearch(data,10,4,0));
	printf("%d\n",binarySearch(data,10,100,0));
}

 

  

 

 

 

 

 

 

posted @ 2014-11-07 10:44  bigbigtree  阅读(591)  评论(0编辑  收藏  举报