순차 탐색 : 리스트 안에 있는 특정한 데이터를 찾기 위해서 앞에서부터 데이터를 하나씩 확인하는 방법
이진 탐색 : 정렬되어있는 리스트에서 탐색 범위를 절반씩 좁혀가며 데이터를 탐색하는 방법
이진 탐색은 시작점, 끝점, 중간점을 이용하여 탐색 범위를 설정합니다.
O(logN)
이진 탐색의 시간 복잡도
단계마다 탐색범위를 2로 나누는 것과 동일하므로 연산횟수는 log₂N 에 비례합니다.
예를 들어 초기 데이터 개수가 32개일 때, 이상적으로 1단계를 거치면 16개 가량의 데이터만 남습니다.
2단계를 거치면 8개 가량의 데이터만 남습니다.
3단계를 거치면 4개 가량의 데이터만 남습니다.
다시 말해 이진 탐색은 탐색 범위를 절반씩 줄이며, 시간 복잡도는 O(logN)을 보장합니다.
이진 탐색 소스코드: 재귀적 구현 (Python)
# 이진탐색 재귀함수로 구현하기
# target 값이 몇번째에 존재하는지 위치 출력하기
def binary_search(array, target, start, end):
if start > end :
return None
mid = (start + end) // 2
# 찾은 경우 중간점 인덱스 반환
if array[mid] == target:
return mid
# 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인
elif array[mid] > target:
return binary_search(array, target, start, mid-1)
else:
return binary_search(array, target, mid + 1, end)
# 전체 원소개수 n, 목표 타겟 target
n, target = map(int, input().split())
array = list(map(int, input().split()))
result = binary_search(array, target, 0, n-1)
if result == None:
print('원소가 존재하지 않습니다.')
else:
print(result+1, '번째에 원소가 존재합니다.')
# 10 7
# 1 3 5 7 9 11 13 15 17 19
# 1 3 5 6 9 11 13 15 17 19
이진 탐색 소스코드: 반복문 구현 (Python)
# 이진탐색 재귀함수로 구현하기
# target 값이 몇번째에 존재하는지 위치 출력하기
def binary_search(array, target, start, end):
While start <= end:
mid = (start + end) // 2
# 찾은 경우 중간점 인덱스 반환
if array[mid] == target:
return mid
# 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인
elif array[mid] > target:
end = mid -1
# 중간점의 값보다 찾고자 하는 값이 작은 경우 오른쪽 확인
else:
start = mid + 1
return None
# 전체 원소개수 n, 목표 타겟 target
n, target = map(int, input().split())
array = list(map(int, input().split()))
result = binary_search(array, target, 0, n-1)
if result == None:
print('원소가 존재하지 않습니다.')
else:
print(result+1, '번째에 원소가 존재합니다.')
# 10 7
# 1 3 5 7 9 11 13 15 17 19
# 1 3 5 6 9 11 13 15 17 19
파이썬 이진 탐색 라이브러리
bisect_left(a, x): 배열 a에 원소 x가 들어갈 수 있는 가장 왼쪽 인덱스를 반환
bisect_right(a, x): 배열 a에 원소 x가 들어갈 수 있는 가장 오른쪽 인덱스를 반환
값이 특정 범위에 속하는 데이터 개수 구하기
# 값이 특정 범위에 속하는 데이터 개수 구하기
from bisect import bisect_left, bisect_right
# 값이 [left_value, right_value]인 데이터의 개수를 반환하는 함수
def count_by_range(a, left_value, right_value):
left_idx = bisect_left(a, left_value)
right_idx = bisect_right(a, right_value)
return right_idx - left_idx
# 배열 선언
a = [1, 2, 3, 3, 3, 3, 4, 4, 8, 9]
# 4의 개수 구하기
print(count_by_range(a, 4, 4))
# 8-6 = 2
# -1, 3 범위 내에 있는 데이터 개수 출력
print(count_by_range(a, -1, 3))
# 6 - 0 = 6
파라메트릭 서치(Parametric Search)
파라메트릭 서치란 최적화 문제를 결정문제('예' 혹은 '아니오')로 바꾸어서 해결하는 기법입니다.
댓글 영역