1. 시작하기 전에
- 아래와 같은 문제가 있을 때, 어떤 방법(=알고리즘)을 사용하는 것이 가장 효율이 좋을지 생각해보자.
생각의 과정
1. 조건 점검하기
- 1~100 사이의 난수가 30개의 병뚜껑에 적혀있고 이 중에 70이 있는지 찾아야 한다.
- 30개의 병뚜껑에는 오름차순으로 숫자가 정렬되어 있다.
- 가장 적은 수의 병을 따서 70을 찾아야 한다.
2. 가장 적은 수의 병을 따는 방법
- 1~30번 후보군의 중간에 위치한 15번 병뚜껑을 확인하여 후보군을 반으로 줄인다.
- 15번 병뚜껑의 숫자가 70보다 작다면 우측(16 ~ 30번 병뚜껑), 70보다 크다면 좌측(1~14번 병뚜껑)을 후보군으로 선정한다.
- 좌측 또는 우측의 후보군이 선정되면 위의 과정을 반복한다.
- 최종적으로 숫자 70을 찾는다.
→ 위에서 설명한 과정(=알고리즘)이 바로 이진 탐색이다. 그렇다면 이진 탐색이 무엇일까?
2. 이진 탐색이란?
- 탐색할 자료를 둘로 나누어 찾는 데이터가 있을만한 곳을 탐색하는 방법
이진 탐색의 동작 - 순차 탐색과 비교를 통한 이해
3. 분할 정복과 이진 탐색의 연관성
a) 분할 정복(Divide & Conquer)
- 분할(Divide): 문제를 하나 또는 둘 이상으로 나눈다.
- 정복(Conquer): 나누어진 문제가 충분히 작고, 해결 가능한 크기라면 해결한다. 반대로, 충분히 작지 않다면 다시 분할한다.
b) 이진 탐색(Binary Search)
- 분할(Divide): 주어진 자료(리스트)를 두 개의 서브리스트로 나눈다.
- 정복(Conquer): 검색할 숫자 > 중간값 이라면, 리스트의 뒷부분에서 검색할 숫자를 찾는다. 반대로, 검색할 숫자 < 중간값 이라면, 리스트의 앞부분에서 검색할 숫자를 찾는다.
4. 코드구현
def binary_search(data, search): #search = 찾는 값
if len(data) == 1 and search == data[0]: #마지막 검색값이 찾는 값인 경우
return True
if len(data) == 1 and search != data[0]:#끝까지 검색했는데 찾는 값이 없는 경우
return False
if len(data) == 0:
return False
median = len(data) // 2
if search == data[median]:
return True
else:
if search > data[median]: #찾는 값이 중간 값보다 크다면
return binary_search(data[median:], search) #뒤쪽 리스트
else: #찾는 값이 중간 값보다 작다면
return binary_search(data[:median], search) #앞쪽 리스트
[테스트 결과]
5. 시간 복잡도
- 이진 탐색은 분할과 정복 과정을 이용하여 처리해야 할 데이터의 대상의 수가 50%씩 줄어든다.
- 그러므로 이진 탐색의 경우의 수는 n x (0.5)^n 이며 연산 결과값이 1이 될 때까지 진행하게 된다.
- 결론으로, 이진 탐색의 시간복잡도는 O(log n)이다.
'컴퓨터공학기초 개념 > 알고리즘 개념' 카테고리의 다른 글
Advanced Algorithm - 그래프의 이해(basic concepts of the graph) (0) | 2020.09.23 |
---|---|
Advanced Algorithm - 순차 탐색(Sequential Search) (0) | 2020.09.22 |
Advanced Algorithm - 병합 정렬 (Merge Sort) (0) | 2020.09.17 |
Advanced Algorithm - 퀵 정렬(Quick Sort) (0) | 2020.09.15 |
Advanced Algorithm - 동적 계획법(DP) & 분할정복(Divide&Conquer) (0) | 2020.09.15 |
댓글