二分查找法

二分查找法又或是折半查找法(Binary search, half-interval search)是一种应用于有序数组中的查找算法,由John William Mauchly首次提出于1946年,但第一个没有bug的二分查找法直至1962年才出现

尽管二分查找的基本思想相对简单,但细节可以令人难以招架 … — 高德纳

基本思想

目的是查找有序数列中的一个元素,比较目标元素与有序数列中心元素的大小,大于该元素则在中心元素右侧部分递归查找,小于该元素则在中心元素左侧部分递归查找

代码实现

//MARK: -无注释纯享版
/// 二分查找
/// - Parameter target: 需要查找的元素
/// - Returns: 如果找到该元素则返回index,未找到则返回-1

func binarySearchA(target: Int) -> Int{
    
    var l: Int = 0
    var r: Int = arr.count - 1
    
    while l <= r {
        
        let mid = l + (r - l)/2
        if arr[mid] == target{
            return mid
        }
        if target < arr[mid] {
            r = mid - 1
        }
        if target > arr[mid] {
            l = mid + 1
        }
    }
    
    return -1
    
}

/// 递归实现的二分查找
/// - Parameters:
///   - target: 需要查找的元素
///   - l: 查找范围的左边界
///   - r: 查找范围的右边界
/// - Returns: 如果找到该元素则返回index,未找到则返回-1
func binarySearhByRecursion(target: Int, l: Int, r: Int) -> Int{
    
    if l > r {
        return -1
    }
    
    let mid = l + (r - l)/2
    
    if arr[mid] == target {
        return mid
    }
    else if target < arr[mid] {
        return binarySearhByRecursion(target: target, l: l, r: mid - 1)
    }
    else {
        return binarySearhByRecursion(target: target, l: mid + 1, r: r)
    }
    
}

递归实现与非递归实现思路基本一致,注释版不再赘述

//MARK: -注释版

/// 二分查找
/// - Parameter target: 需要查找的元素
/// - Returns: 如果找到该元素则返回index,未找到则返回1
func binarySearchB(target: Int) -> Int{
    //在[l...r]中查找
    var l: Int = 0
    
    var r: Int = arr.count - 1
    
    //当 l > r 时说明查找已经结束
    while l <= r {
        //先取数组中心下标
        // let mid = (l + r)/2 的问题在于l与r特别大的情况下可能会产生数据溢出
        let mid = l + (r - l)/2
        
        //第一种情况是中心元素正好是目标元素
        if arr[mid] == target{
            return mid
        }
        //第二种情况是目标元素小于中心元素,则将右边界缩小到中心元素左边第一位
        if target < arr[mid] {
            r = mid - 1
        }
        //第三种情况是目标元素大于中心元素,则将做边界缩小到中心元素右边第一位
        if target > arr[mid] {
            l = mid + 1
        }
    }
    
    return -1
    
}

本篇到此为止,希望这对你有帮助,如果有错误或是有需要补充的地方,望告知。


种一棵树最好的时间是在十年前,而后是现在。

Loading Disqus comments...
Table of Contents