Skip to content

Commit 80de7a9

Browse files
committed
Binary search using recursion.
1 parent 68c2606 commit 80de7a9

1 file changed

Lines changed: 15 additions & 19 deletions

File tree

Sources/SortedArray.swift

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,13 @@ fileprivate enum Match<Index: Comparable> {
358358
case notFound(insertAt: Index)
359359
}
360360

361+
extension Range where Bound == Int {
362+
var middle: Int? {
363+
guard !isEmpty else { return nil }
364+
return lowerBound + count / 2
365+
}
366+
}
367+
361368
extension SortedArray {
362369
/// Searches the array for `element` using binary search.
363370
///
@@ -375,26 +382,15 @@ extension SortedArray {
375382
}
376383

377384
fileprivate func search(for element: Element, in range: Range<Index>) -> Match<Index> {
378-
guard !range.isEmpty else { return .notFound(insertAt: range.upperBound) }
379-
var left = range.lowerBound
380-
var right = index(before: range.upperBound)
381-
382-
while left <= right {
383-
let dist = distance(from: left, to: right)
384-
let mid = index(left, offsetBy: dist/2)
385-
let candidate = self[mid]
386-
387-
switch compare(candidate, element) {
388-
case .orderedAscending:
389-
left = index(after: mid)
390-
case .orderedDescending:
391-
right = index(before: mid)
392-
case .orderedSame:
393-
return .found(at: mid)
394-
}
385+
guard let middle = range.middle else { return .notFound(insertAt: range.upperBound) }
386+
switch compare(element, self[middle]) {
387+
case .orderedDescending:
388+
return search(for: element, in: index(after: middle)..<range.upperBound)
389+
case .orderedAscending:
390+
return search(for: element, in: range.lowerBound..<middle)
391+
case .orderedSame:
392+
return .found(at: middle)
395393
}
396-
// Not found. left is the index where this element should be placed if it were inserted.
397-
return .notFound(insertAt: left)
398394
}
399395
}
400396

0 commit comments

Comments
 (0)