정렬되어 있는 데이터에서 원하는 값을 찾아내는 알고리즘. 주어진 데이터의 중앙값과 찾고자 하는 값을 비교해 데이터의 크기를 절반씩 줄이면서 대상을 찾는 방법.
* 특징
오름차순으로 정렬된 데이터에서 다음 4가지 과정을 반복한다.
- 현재 데이터셋의 중앙값(median)을 선택한다.
- 중앙값 > 타깃 데이터(taget data)일 때 중앙값 기준으로 왼쪽 데이터셋을 선택한다.
- 중앙값 < 타깃 데이터일 때 주앙값 기준으로 오른쪽 데이터셋을 선택한다.
- 과정 1~3을 반복하다가 중앙값 == 타깃 데이터일 때 탐색을 종료한다.
1 3 5 7 9 11 13 15 17 19
- 중간 인덱스(left + right) / 2를 선택합니다. -> 중간 인덱스는 (0 + 9) / 2 = 4
- 중간 값인 9와 찾고자 하는 값인 11이 일치하지 않으므로 탐색 범위를 다시 좁힌다.
- 찾고자 하는 값이 중간값보다 크므로, 중간값의 오른쪽 부분 배열에서 탐색을 시작한다. -> 중간 인덱스 + 1부터 right까지(인덱스 5 ~ 9) 탐색.
- 중간 인덱스를 다시 선택 -> (5 + 9) / 2 = 7
- 위 과정을 반복하여서 11을 찾는다.
// 매개변수로 배열 arr, 찾고자 하는 값 target, 배열의 왼쪽 끝을 가리키는 left, 배열의 오른쪽 끝을 가리키는 right를 전달받는다.
public static int binarySearchRecursive(int[] arr, int target, int left, int right) {
if (left > right) {
return -1;
}
// 현재 검색 범위의 중간값을 구하고, 이 값이 찾고자 하는 값인지 확인
int mid = (left + right) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] > target) { // 만약 찾고자 하는 값이 중간값보다 작다면, 중간값의 왼쪽 부분 배열에서 재귀적으로 탐색
return binarySearchRecursive(arr, target, left, mid - 1);
} else { // 찾고자 하는 값이 중간값보다 크다면, 중간값의 오른쪽 부분 배열에서 재귀적으로 탐색
return binarySearchRecursive(arr, target, mid + 1, right);
}
}
public static int binarySearch(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
//현재 검색 범위의 중간값을 구하고,
int mid = (left + right) / 2;
//이 값이 찾고자 하는 값인지 확인
if (arr[mid] == target) {
return mid;
} else if (arr[mid] > target) { // 찾고자 하는 값이 중간값보다 작다면, 중간값의 왼쪽 부분 배열에서 탐색을 수행해야 하므로 right 포인터를 중간값의 왼쪽으로 이동
right = mid - 1;
} else { // 고자 하는 값이 중간값보다 크다면, 중간값의 오른쪽 부분 배열에서 탐색을 수행해야 하므로 left 포인터를 중간값의 오른쪽으로 이동
left = mid + 1;
}
}
return -1;
}