二分查找(Binary Search)

来源:互联网 发布:Windows 匿名event 编辑:程序博客网 时间:2024/04/23 14:54
一、顺序查找(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 implementationint 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)

原创粉丝点击