二分查找(Binary Search)

一、顺序查找(linear search)
问题描述:在一个给定的序列A[]中查找指定元素v,若查找成功则返回元素在数组中的下标,否则返回-1。

C++实现:

//简单线性查找 
int linearSearch(int *a, int n, int key)
{
    for(int i=0; i<n; i++)
    {
        if(a[i] == key)
        {
            return i;
        }
    }
    return -1;
}

(1)最好情况下,比较一次就查找成功

(2)最坏情况下,比较n次查找成功或查找失败

(3)假设数组中的n个元素以等可能的概率被查找,且待查找的数在数组中,则平均查找长度为: (n+1)/2

(4)综上,线性查找的时间复杂度为:Ο(n)


二、二分查找(binary search)

思想:当待查找序列是有序序列时, 不用像线性查找那样一个接一个的比较,我们可以把序列中点和检索值v进行比较,快速缩小比较范围,从而节省时间。
1.迭代实现
//binary search iterative implementation 
int binarySearch(int *a, int n, int key)
{
    int low = 0;
    int high = n-1;
    int mid ;
    
    while(low <= high)
    {
        mid = (low + high)/2;
        if(a[mid] == key)
            return mid;
        else if(a[mid] < key)
            low = mid + 1;
        else high = mid - 1;
    }
    return -1;
}
2.递归实现
//binary search recursive implementation
int binarySearch(int *a, int low, int high, int key)
{
    if(low <= high)
    {
        int mid = (low + high)/2;
        if(a[mid] == key)
            return mid;
        else if(a[mid] < key)
            return binarySearch(a,mid+1,high,key);
        else
            return binarySearch(a,low,mid-1,key);
    }
    return -1;
}
算法时间复杂度分析:
(1)根据迭代算法我们可以画出查找过程的判定树,判定树的高度为lgn,也就是最多比较lgn次,因而算法的时间复杂度为Ο(lgn)
(2)由于问题的输入规模不断减半,所以递归最多lgn层,每次递归代价为常数,算法复杂度为Ο(lgn )
==================================================================================

补充问题:

集合S由n个整数构成,给定一个整数x,判断集合中是否存在两个数,其和为x,存在返回true,否则返回false。要求算法的时间复杂度为O(nlgn)
分析:
(1)把n个元素按非递减排序 复杂度可以达到O(nlgn),如归并排序,堆排序
(2)从第一个元素开始运用二分查找,对于元素 a[i] 检索是否存在元素x-a[i]
核心代码:
bool exist(int* a, int n)
{
    mergeSort(a,n);
    for(int i=0; i<n-1; i++)
    { 
        if(binarySearch(a,0,n-1,x-a[i]) != -1) 
        { 
            return true;  
        }
    } 
    return false;
}
由于外层循环n次,循环体内的二分查找复杂度为O(lgn),该核心代码的复杂度为O(nlgn)
综上,算法总的复杂度为O(nlgn)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值