zoukankan      html  css  js  c++  java
  • 二分搜索 一种比较完美的实现方法

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


    代码如下:

    
    
    //递归版本
    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
    ",binarySearch(data,10,4,1));
    	
    	printf("%d
    ",binarySearch(data,10,60,1));
    	printf("%d
    ",binarySearch(data,10,60,0));
    	printf("%d
    ",binarySearch(data,10,55,0));
    	printf("%d
    ",binarySearch(data,10,89,0));
    	printf("%d
    ",binarySearch(data,10,89,1));
    	printf("%d
    ",binarySearch(data,10,4,0));
    	printf("%d
    ",binarySearch(data,10,100,0));
    }
    

      

     

     

     

     

     

  • 相关阅读:
    CF432D Prefixes and Suffixes
    CF126B Password
    如何实现输入历史记录功能
    python工作中总结
    今 天看到我十年前的一篇技术文章,想到不知不觉学编程十多年了,,
    现在互联网好多bug 想到都烦
    【图论】割点
    【DP】【P1941】【NOIP2014D1T3】飞扬的小鸟
    【线段树】【P3740】 [HAOI2014]贴海报
    【单调队列】【P1714】 切蛋糕
  • 原文地址:https://www.cnblogs.com/bigbigtree/p/4080677.html
Copyright © 2011-2022 走看看