티스토리 뷰
이진 탐색 ( Birnary Search )
🤔 단순 탐색과 문제점
사전에서 정지 라는 단어를 찾는다고 생각해보자. 보통의 사전은 자음과 모음 순으로 정렬되어 있다.
정렬되어 있다는 사실을 알았으니 우리는 ㄱ ~ ㅈ 까지 찾은 후 ㅏ ~ ㅓ 까지 찾아갈 것이다. 이렇게 앞에서부터 순서대로 찾아나가는 방법을 단순 탐색 이라고 부른다.
다만 이런 방식은 상당히 비효율 적일 수 있다. 만약 앞에서 32000번째 단어의 경우 찾기 위해 앞에서 부터 32000개의 단어를 확인 해보아야 한다.
💡 즉, M개의 정렬된 데이터를 찾기 위해 최대 M번 최소 1번 평균적으로 M/2번의 탐색 횟수가 필요하다.
👍 이진 탐색 ( Binary Search )
단순 탐색(Simple Search) 방식은 데이터의 개수가 늘어남에 따라 탐색 횟수도 늘어난다. 데이터 개수가 커질 수록 그 속도가 늦어진다는 의미다. 정렬된 데이터에 있어 해당 문제를 해결하는 더 빠른 방법이 있는데, 바로 이진 탐색 방법이다.
이진 탐색 설명을 위해 다시 사전에서 정지 라는 단어를 찾아보자. 자음 ㄱ~ㅎ 에서 ㅈ 은 그 중간인 ㅅ 보다 뒤쪽에 위치해있다. 그러면 앞에 ㄱ~ㅅ 을 버리자. 그리고 ㅇ~ㅎ 에 중간을 기준으로 다시 찾아 볼 수 있다. 이와 같이 정렬된 데이터의 중간을 기준으로 비교하는 과정을 반복해 나가며 탐색하는 방법을 이진 탐색( Binary Search ) 라고 한다.
이진 탐색은 탐색 횟수를 줄일 수 있다. 정렬된 10만개의 단어중 특정 단어를 찾기위해 아무리 많아도 log_{2}10000 번이면 충분하다.
💡 즉, M개의 정렬된 데이터를 찾기 위해 최대 log_{2} M번 최소 1번의 탐색 횟수가 필요하다. 이진탐색의 시간 복잡도는 O(log_{2} M) 이다.
이진탐색 평균 횟수 테스트
코드
이진 탐색 메서드
public class BinarySearch {
public int binarySearch(int arr[], int target) {
int searchCount = 0;
int low = 0;
int high = arr.length - 1;
int mid;
while(low <= high) {
mid = (low + high) / 2;
if (arr[mid] == target){
searchCount++;
return searchCount;
}
else if (arr[mid] > target) {
high = mid - 1;
searchCount++;
}
else {
low = mid + 1;
searchCount++;
}
}
return -1;
}
}
Test
public class Test {
public static final int NUMBERS = 100;
public static final int MAX_VALUE = 100000000;
static BinarySearch search = new BinarySearch();
public static void main(String[] args) {
long countTotal = 0L;
for (int i = 0; i < MAX_VALUE; i++) {
int target = (int) (Math.random() * NUMBERS + 1);
int[] array = Arrays.stream(IntStream.range(1, NUMBERS).toArray()).toArray();
int count = search.binarySearch(array, target);
countTotal += count;
}
long avgCount = countTotal / MAX_VALUE;
System.out.println(avgCount);
}
// 1_000 대해 100000000번 테스트 평균 5회
}
📝 1~100 까지 수를 100000000번 테스트 했을 때 평균 탐색 횟수 5회
참조
'Algorithm' 카테고리의 다른 글
배열(Array)과 연결리스트(List) (0) | 2022.09.25 |
---|---|
B-Tree와 B+Tree (0) | 2022.08.09 |
해시 함수와 해시 테이블 (0) | 2022.07.17 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 메모리 파편화
- 객체 풀
- 메모리 단편화
- OOP
- multimap
- 내부 단편화
- Clean Architecture
- java
- 외부 단편화
- Sticky Session
- pool
- RestAssured
- 세션 불일치
- Session
- 육각형 아키텍처
- 뾰족함
- 수평 분할
- 동적 디스패치
- SpringBoot 2.2
- pass by value
- Memory Fragmentation
- 수직 분할
- 정적 타입 언어
- 동적 타입 언어
- 장애 해결기
- pass by reference
- 컴포짓 패턴
- Object Pool
- ATDD
- 클린 아키텍처
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함