二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
它充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用O(log n)完成搜索任务。它的基本思想是:(这里假设数组元素呈升序排列)将n个元素分成个数大致相同的两半,取a[n/2]与欲查找的x作比较,如果x=a[n/2]则找到x,算法终止;如 果xa[n/2],则我们只要在[数组](https://baike.baidu.com/item/%E6%95%B0%E7%BB%84)a的左半部继续搜索x;如果xa[n/2],则我们只要在数组a的右 半部继续搜索x。
有序查找时间复杂度为O(n) 二分查找时间复杂度为O(log n)
swift示例代码:
func testBinary(){var pArr:[Person] = []for i in 0..<10 {let p = Person.init(age: i*2+1)pArr.append(p)}let index = binarySearch(pArr, key: Person.init(age: 13))print("index===\(index ?? -1)")}///二分查找func binarySearch<T: Comparable>(_ a: [T], key: T) -> Int? {///左序号var lowerBound = 0///右序号var upperBound = a.count///执行逻辑while lowerBound < upperBound {///1.计算中间序号 --> n/2///2.取中间序号对应的值 与需要查找的key做比较let midIndex = (lowerBound + upperBound) / 2if a[midIndex] == key {/// 相等则返回对应的序号return midIndex} else if a[midIndex] < key {///如果middle的值 小于key 则说明key在middle的右边///改变左序号---->从而改变了下次middle对应的序号lowerBound = midIndex + 1} else {///如果middle的值 大于key 则说明key在middle的左边///改变右序号---->从而改变了下次middle对应的序号upperBound = midIndex - 1}}return nil}///有序查找func sequenceSearch<T: Comparable>(_ a: [T], key: T) -> Int? {for i in 0..<a.count {if a[i] == key {return i}}return nil}class Person:Comparable{static func < (lhs: Person, rhs: Person) -> Bool {return lhs.age < rhs.age}static func == (lhs: Person, rhs: Person) -> Bool {return lhs.age == rhs.age}static func > (lhs: Person, rhs: Person) -> Bool {return lhs.age > rhs.age}var age:Int = 0init(age:Int){self.age = age}}
