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的八个步骤,而是只需要三个。这是它的工作原理:
第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.)时间复杂性,如果您正在进行重复查找,则为大数据集更好地缩放。