Binary Search - 二分查找法(折半查找法)


问题

在长度为的升序(从小到大)序列中查找元素的位置。

解法

,元素的关系有三种情况:

(1) 若,显然已经查询到元素的位置,算法结束;

(2) 若,则处于左边;

(3) 若,则处于右边;

该操作用伪代码表示为:

function Search(s, low, high, x):
    let mid = (low + high) / 2
    if x = s[mid]
        return true, mid
    else if x < s[mid]
        return false, low, mid-1
    else if x > s[mid]
        return false, mid+1, high

(1) Search函数第2行:计算搜索范围的中间位置,以为基准与进行比较;

(2) Search函数第3-8行:比较,若则找到结果,若则在继续寻找,若则在继续寻找;

上述操作,可以用下图中的示例:

,可以直接找到

BinarySearch1.png

,则令之后继续搜索:

BinarySearch2.png

,则令之后继续搜索:

BinarySearch3.png

外围只需循环调用Search函数即可:

function BinarySearch(s, n, x):
    let low = 0, high = n-1
    while low <= high
        let found, low, high = Search(s, low, high, x)
        if found
            return low
    return -1

复杂度

Search函数的输入规模为,该函数中最多有1次加法、1次除法、3次比较操作,因此时间复杂度为

BinarySearch函数的输入规模为,每次调用Search函数后的值都会减小一半,即

假设递归层数为,可得:

即:

代入原始递推公式,可得:

该算法时间复杂度为,空间复杂度为

源码

BinarySearch.h

BinarySearch.cpp

测试

BinarySearchTest.cpp