美文网首页
【数据结构与算法 - Swift实现】11 - 二分查找 (Bi

【数据结构与算法 - Swift实现】11 - 二分查找 (Bi

作者: Lebron_James | 来源:发表于2019-05-07 00:06 被阅读0次

二分查找是高效搜索算法中的一员,时间复杂度为O(log n)。使用搜索算法前,需要满足两个条件:

  • 集合中的元素必须可以使用索引直接访问,在 Swift 中,这个集合必须是RandomAccessCollection类型。
  • 集合中的元素必须是有序的

实现

假设要查找的元素为 A,集合从小到大的顺序排列,二分查找的步骤如下:

  • 首先找到中间元素
  • 拿 A 与中间元素对比,如果 A 等于中间元素,直接返回索引,否则继续下列步骤
  • 如果 A 小于中间元素,则用所有左边元素组成的集合进行递归;如果 A 大于中间元素,则用所有有边元素组成的集合进行递归

实现代码如下:

extension RandomAccessCollection where Element: Comparable {
    func binarySearch(for value: Element,
                      in range: Range<Index>? = nil) -> Index? {
        
        let range = range ?? startIndex..<endIndex
        guard range.lowerBound < range.upperBound else { return nil }
        
        let size = distance(from: range.lowerBound, to: range.upperBound)
        let middle = index(range.lowerBound, offsetBy: size / 2)
        let middleValue = self[middle]
        
        if middleValue == value {
            return middle
            
        } else if value < middleValue {
            return binarySearch(for: value, in: range.lowerBound..<middle)
            
        } else {
            return binarySearch(for: value, in: middle..<range.upperBound)
        }
    }
}

代码解析:

  • 上面已经提到,要使用二分法的必须是 RandomAccessCollection 类型,所以我们通过扩展这个协议来实现二分查找,并且 Element 必须是 Comparable
  • 因为我们要使用递归,所以方法中需要 range 参数
  • 定义 range 变量,如果 range 为空,则默认是原来数组的整个范围
  • 判断传入的范围中,是否包含至少一个元素,如果不包含直接返回 nil
  • 读取中间元素的值
  • 中间元素和要查找的值进行对比,如果相等,直接返回中间索引;如果要查找的值小于中间元素,用左边的范围继续查找;如果要查找的值大于中间元素,用右边的范围继续查找

测试如下:

let array = [0, 9, 13, 20, 21, 25, 35, 120, 250]

let indexOf = array.index(of: 20)
let binarySearchFor = array.binarySearch(for: 20)

print("index(of:): \(String(describing: indexOf))")
print("binarySearch(for:): \(String(describing: binarySearchFor))")

// 结果
index(of:): Optional(3)
binarySearch(for:): Optional(3)

完整代码 >>

参考资料

Data Structures and Algorithms in Swift --- raywenderlich.com,如果想看原版书籍,请点击链接购买。

欢迎加入我管理的Swift开发群:536353151

下一篇文章:【数据结构与算法 - Swift实现】12 - 时间复杂度为O(n^2)的排序算法

相关文章

  • 分治算法(swift二分法排序递归实现)

    二分查找 1、二分查找(Binary Search) 2、二分查找的基本思想 swift算法实现

  • 【数据结构与算法 - Swift实现】11 - 二分查找 (Bi

    二分查找是高效搜索算法中的一员,时间复杂度为O(log n)。使用搜索算法前,需要满足两个条件: 集合中的元素必须...

  • 排序算法

    算法与数据结构基础 查找算法: 二分查找法: 简介:二分查找法又被称为折半查找法,用于预排序的查找问题 过程: 如...

  • 带领初学者学习数据结构与算法免费视频教程

    带领初学者学习数据结构与算法免费视频教程(2 个视频) 详解使用 JavaScript 实现二分查找算法「12:3...

  • 二分查找

    二分查找是一种查询效率非常高的查找算法。又称折半查找。 起初在数据结构中学习递归时实现二分查找,实际上不用递归也可...

  • java实现二分查找-两种方式

    二分查找是一种查询效率非常高的查找算法。又称折半查找。 起初在数据结构中学习递归时实现二分查找,实际上不用递归也可...

  • 【爬虫】数据结构实现折半查找的算法

    数据结构实现折半查找的算法 折半查找技术,也就是二分查找,通常称为二分法查找。它的前期是线性表中的记录必须是关键码...

  • 2019-10-27文章阅读

    二分查找(上):如何用最省内存的方式实现快速查找功能? 来源:王争的数据结构与算法之美时间复杂度为O(logn) ...

  • 数据结构与算法--散列表

    数据结构与算法--散列表 之前学习了基于链表的顺序查找、基于有序数组的二分查找、二叉查找树、红黑树,这些算法在查找...

  • 数据结构与算法 树 引言 顺序查找 ​ 哨兵的方式 ​ 时间复杂度为O(N) 二分查找查找树的形式我...

网友评论

      本文标题:【数据结构与算法 - Swift实现】11 - 二分查找 (Bi

      本文链接:https://www.haomeiwen.com/subject/jukjoqtx.html