首页 iOS.& Swift Books 数据结构& Algorithms in Swift

20
二进制搜索 由凯尔文刘写

二进制搜索是具有时间复杂性的最有效的搜索算法之一 O(log n.)。这与搜索一个元素相当 均衡 binary search tree.

可以使用二进制搜索之前需要满足的两个条件:

  • 集合必须是 able to perform index manipulation in constant time. This means that the collection must be a RandomAccessCollection.
  • 集合必须是 分类.

例子

The benefits of binary search are best illustrated by comparing it with linear search. Swift’s Array type uses linear search to implement its firstIndex(of:) method. This means that it traverses through the whole collection or until it finds the element:

线性搜索值31。
线性搜索值31。

二进制搜索通过利用该集合已经排序的事实来处理不同的东西。

以下是应用二进制搜索以查找该值的示例 31:

二进制搜索值31。
二进制搜索值31。

而不是找到31的八个步骤,而是只需要三个。这是它的工作原理:

第1步:找到中间指数

第一步是找到收集的中间索引。这相当简单:

第2步:检查中间索引处的元素

下一步是检查存储在中间索引处的元素。如果它与您要查找的值匹配,则返回索引。否则,您将继续步骤3。

第3步:递归调用二进制搜索

最后一步是递归地调用二进制搜索。但是,这次,您只会将元素完全考虑到 剩下 或者到 中间索引,取决于您正在搜索的价值。如果您搜索的值小于中间值,则搜索左后。如果它大于中间值,则搜索正确的子序列。

执行

打开本章的入门游乐场。创建一个新文件 来源 文件夹命名 binarysearch.swift.。将以下内容添加到文件中:

// 1
public extension RandomAccessCollection where Element: Comparable {
  // 2
  func binarySearch(for value: Element, in range: Range<Index>? = nil)
      -> Index? {
    // more to come
  }
}

// 1
let range = range ?? startIndex..<endIndex
// 2
guard range.lowerBound < range.upperBound else {
  return nil
}
// 3
let size = distance(from: range.lowerBound, to: range.upperBound)
let middle = index(range.lowerBound, offsetBy: size / 2)
// 4
if self[middle] == value {
  return middle
// 5
} else if self[middle] > value {
  return binarySearch(for: value, in: range.lowerBound..<middle)
} else {
  return binarySearch(for: value, in: index(after: middle)..<range.upperBound)
}
let array = [1, 5, 15, 17, 19, 22, 24, 31, 105, 150]

let search31 = array.firstIndex(of: 31)
let binarySearch31 = array.binarySearch(for: 31)

print("firstIndex(of:): \(String(describing: search31))")
print("binarySearch(for:): \(String(describing: binarySearch31))")
index(of:): Optional(7)
binarySearch(for:): Optional(7)

关键点

  • 二进制搜索只是一种有效的算法 分类 collections.
  • 有时,对一个集合进行排序只是为了利用二进制搜索能力来查找元素可能是有益的。
  • The firstIndex(of:) method on sequences uses linear search, which has a O(n)时间复杂性。二进制搜索有一个 O(log n.)时间复杂性,如果您正在进行重复查找,则为大数据集更好地缩放。

有一个技术问题?想报告一个错误吗? 您可以向官方书籍论坛中的书籍作者提出问题和报告错误 这里.

有反馈分享在线阅读体验吗? 如果您有关于UI,UX,突出显示或我们在线阅读器的其他功能的反馈,您可以将其发送到设计团队,其中表格如下所示:

© 2021 Razeware LLC

您可以免费读取,本章的部分显示为 混淆了 文本。解锁这本书,以及我们整个书籍和视频目录,带有Raywenderlich.com的专业订阅。

现在解锁

要突出或记笔记,您需要在订阅中拥有这本书或自行购买。