이진 탐색이란 데이터가 정렬돼 있는 배열에서 특정한 값을 찾아내는 알고리즘이다. 탐색 범위를 두 부분으로 분할하면서 찾는 방식으로, 처음부터 끝까지 돌면서 탐색하는 것보다 훨씬 빠르다는 장점을 갖고 있다.
n개의 원소를 담고 있는 배열 arr에서 특정값 m을 찾는다
low는 탐색 범위의 최소값이고, high는 탐색 범위에서의 최대값이다. 비교 결과에 따라 low의 값을 높이거나 high의 값을 줄이면 탐색 범위가 줄어들게 되는데, mid와 m을 비교함으로써 탐색 범위를 반으로 줄여나가는 것이다.
void binarySearch() {
int[] arr = {23, 87, 65, 12, 57, 32, 99, 81};
int m = 32; // 배열에서 32를 찾는다.
int index = -1; // 정렬 후 m의 인덱스 번호
Arrays.sort(arr); // 이진 탐색 실행하기에 앞서 배열 오름차순 정렬
int low = 0, high = arr.length-1;
while (low <= high) {
int mid = (low + high) / 2;
if (arr[mid] == m) { // m을 찾았을 떄
index = mid;
break;
}
else if (arr[mid] < m) // mid 인덱스의 원소가 m보다 작을 때
low = mid + 1;
else // mid 인덱스의 원소가 m보다 클 때
high = mid - 1;
}
System.out.println(index); // 2 출력
}
배열(arr) : 23 87 65 12 57 32 99 81
구하려는 값(m) : 32
만약, 배열에 없는 33을 찾는다고 가정해보자.
2회전까지의 과정은 같고, 3회전부터 보도록 하겠다.
low가 high보다 커질 때까지 실행하는 것은 위의 예시와 같이 찾으려고 하는 값이 배열에 없을 때 무한으로 while문이 돌아가는 것을 막기 위한 조건이다.
장점
처음부터 끝까지 하나씩 검사하며 탐색하는 순차 탐색(Sequential Search)의 시간복잡도는 O(n)이다.
순차 탐색과 비교했을 때, 훨씬 빠르다는 장점을 가지고 있다.
단점
정렬된 리스트에만 사용할 수 있다.