- 컬렉션 요소의 접근 시간이 상수시간이어야 하기 때문에 RandomAccessCollection 프로토콜을 준수해야 한다.
- 컬렉션은 정렬되어야 한다.
- 중간 인덱스를 확인한다.
- 찾고자 하는 값과 일치하면 인덱스를 반환하고 아니면 다음 순서를 진행한다.
- 중간 인덱스 기준 작으면 왼쪽, 크면 오른쪽 시퀀스만 고려한다. 이를 값을 찾을 때 까지 반복한다.
RandomAccessCollection
을 준수한 배열에 바로 사용하는 방법public extension RandomAccessCollection where Element: Comparable {
func binarySearch(for value: Element, in range: Range<Index>? = nil) -> Index? {
let range = range ?? stratIndex..<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)
if self[middle] == value {
return middle
} else if self[middle] > value {
return binarySearch(for: value, in: range.lowerBound..<middle)
} else {
return binarySearch(for: value, in: index(after: middle)..<range.upperBound)
}
}
}
func binarySearch(_ array: [Int], _ target: Int, _ startIndex: Int, _ endIndex: Int) -> Int? {
var startIndex = startIndex
var endIndex = endIndex
while startIndex <= endIndex {
let mid = (startIndex + endIndex) / 2
if array[mid] == target {
return mid
} else if array[mid] > target {
endIndex = mid - 1
} else {
startIndex = mid + 1
}
}
return nil
}
let array = [1, 5, 15, 17, 19, 22, 24, 31, 105, 150]
let search31 = array.firstIndex(of: 31)
let binarySearch31 = array.binarySearch(for: 31)
let binartSearch31_2 = binarySearch(array, 31, 0, array.count - 1)
print("firstIndex: \(String(describing: search31))")
print("binarySearch: \(String(describing: binarySearch31))")
print("binartSearch_2 : \(binartSearch31_2)")
firstIndex: Optional(7)
binarySearch: Optional(7)
binartSearch_2 : Optional(7)
제가 학습한 내용을 요약하여 정리한 것입니다. 내용에 오류가 있을 수 있으며, 어떠한 피드백도 감사히 받겠습니다.
감사합니다