您的位置:首页 > 其它

查找问题整理(1)二分查找

2013-07-29 14:18 357 查看
前几篇文章写了排序和排序相关的几个简单易懂的算法。

查找,是和排序密不可分的一个话题。

一般而言,排序之后才能完成查找.如果没有排序,那必须至少把所有数据都遍历一遍才能完成查找,否则将无法保证没有遗漏元素。常见的查找算法是二分查找。

使用二分查找的前提是,待查找的数组必须已经完成了排序。

int binary_search(int* arr, int st, int ed, int number) 
//arr代表待查找的数组的地址,注意这个数组必须已经排好序了。st代表数组的起始位置的下标,ed代表数组的结束位置的下标,number代表带查找的数字。
{
    // The array should be sorted 
    int mid=0;
    while(st<=ed)//注意不能写成st<ed,否则会漏掉最后只剩一个元素的情况,比如,将无法通过测试案例:{0,2}中查找2的测试案例,{2}中查找2和测试案例
    {
        mid = st + (ed-st)/2;//避免(st+ed)/2这种写法可能造成的溢出。
        if(arr[mid]<number)
        {
            st = mid+1;
        }
        else if(arr[mid]>number)
        {
            ed = mid-1;
        }
        else 
        {
            return mid;
        }
    }
    
    return -1;
}
它的main函数如下

int main()
{
   int sorted_arr[10]={4,6,9,11,12,27,27,27,29,30};
   std::cout<<binary_search(sorted_arr, 0, 9, 27)<<std::endl;
}
输出结果:7

也就是说,27位于数组中的第5,6,7位,二分查找输出结果为第7位。现在略微增加一个要求,如果当待查找的数字在数组中有多个时,指定输出第一次出现的数字,该如何改写呢?可以这样改写,

int binary_search(int* arr, int st, int ed, int number)
{
    // The array should be sorted 
    int mid=0;
    while(st<=ed)
    {
        mid = st + (ed-st)/2;
        if(arr[mid]<number)
        {
            st = mid+1;
        }
        else if(arr[mid]>number)
        {
            ed = mid-1;
        }
        else 
        {
            int  temp = mid - 1;
            /**当数组中有多个待查数字时,找到最小的index**/
            while(arr[mid] == arr[temp])  
            {
                temp--;
                mid--;
            }
            /**当数组中有多个待查数字时,找到最小的index**/
            return mid;
        }
    }
    
    return -1;
}


最近又写了写二分查找,这次写的是递归版本了。使劲儿do search work进行了一个100% bug free和效率优化的过程。

int binary_search(int* array,int left, int right, int key) {
    if(left<=right){ //注意① if条件不能少。
        int mid=left+((right-left)>>1);//注意② 这样的写法和"int mid=(left+right)/2"相比,不仅能够避免溢出,而且能够提高效率(右移高于除法)。
        if(array[mid]<key) 
            return binary_search(array, mid+1, right, key);
        else if(array[mid]>key)
            return binary_search(array, left, mid-1, key);
        else
            return mid; //注意③ 把相等的情况放在最后是因为相等的情况比不等的情况更少见。
    }else{
        return -1; //注意④ 若找不到key,在这里处理。
    } 
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: