[python]이진 탐색 알고리즘

한상욱·2023년 8월 30일
0

알고리즘 with python

목록 보기
6/13
post-thumbnail

들어가며

이글은 동빈나님의 이코테 강의를 보며 정리한 글입니다.

이전에 알아본 DFS, BFS는 그래프 탐색 알고리즘입니다. 그러나, 그래프가 아닌 선형데이터를 탐색할 수도 있지요. 그럴 경우에는 순차 탐색 혹은 이진 탐색 알고리즘을 사용할 수 있습니다.

순차 탐색

순차 탐색은 말 그대로 선형데이터를 앞에서부터 하나씩 확인하는 방법입니다. 1부터 9까지 존재하는 배열에서 8을 찾기 위해 순차 탐색한다고 하겠습니다. 가장 먼저 맨 처음 데이터인 1을 확인합니다.

이제 1은 8이 아닙니다. 이제 다음 데이터를 확인합니다.

2역시 8과 같지 않습니다. 이렇게 순서대로 확인하다가 8번째에서 8을 찾을 수 있습니다.

이 경우에는 데이터의 갯수 NN에 따라서 빅오 표기법으로 O(n)O(n)의 시간복잡도를 가집니다.

이진 탐색

이진 탐색은 순차 탐색과 다르게 시작점과 끝점, 그리고 중간점을 이용해서 탐색합니다. 마찬가지로 1부터 9까지 존재하는 배열에서 8을 찾는다고 하겠습니다.

이진 탐색에서는 시작점과 끝점을 이용해서 중간점을 찾을 수 있습니다. 이 배열에서 0번 인덱스 값인 1과 8번 인덱스값인 9는 각각 시작점과 끝점이라고 할 수 있습니다. 이 때, 각 인덱스의 합을 2로 나눈 값인 인덱스가 중간점이됩니다.

이경우에는 (0+8)/2 이므로 4번 인덱스 값인 5가 중간값이 됩니다. 찾고자 하는 값인 8은 중간점인 값인 5보다 크므로 중간점을 포함해서 왼쪽의 데이터들은 볼 필요가 없습니다. 그리고 이렇게 되면 시작점과 끝점을 다시 정의하게 됩니다.

남은 데이터중 가장 첫번째인 5번 인덱스가 시작점이 됩니다. 끝점은 이전과 동일해요. 그리고 5번 인덱스와 8번 인덱스의 중간점은 (5+8)/2=6.5 지만, 소숫점은 버림하여 6번 인덱스가 중간값이 됩니다.

역시나 중간값보다 8이 더 크므로 중간값의 왼쪽 데이터들은 모두 없앱니다.

자, 남은 데이터 중 가장 첫번째인 7번 인덱스의 값 8이 시작점, 끝점은 동일합니다. 중간값은 (7+8)/2 =7.5입니다. 소숫점은 버리기 때문에 7번 인덱스가 시작점인 동시에 중간점이 됩니다.

이 경우에는 중간점과 찾고자하는 값이 동일하므로 탐색을 종료하게 됩니다.

자, 순차탐색과 다르게 탐색범위를 계속해서 절반으로 줄이기 때문에 시간복잡도는 O(logN)O(logN)를 보장합니다.

이제, python코드로 작성된 이진탐색을 알아보겠습니다.

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)
    # 중간값보다 오른쪽에 있는 경우
    elif array[mid] < target:
    	return binary_search(array, target, mid+1, end)
        
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
result = binary_search(arr, 8, 0, 8)
if result == None:
	print("존재하지 않음")
else:
	print(result+1)

python에서 이진 탐색은 재귀함수를 통해서 구현할 수 있습니다. 가장 먼저 시작점이 끝점보다 큰 경우에는 목표값이 존재하지 않는 경우입니다. 이런 경우에는 None을 반환해줍니다.

중간값과 목표값이 같은 경우에는 값을 찾은것이기 때문에 중간값을 반환합니다. 그 외에 경우에는 끝점 혹은 시작점을 수정한 후 재귀함수를 호출하면 됩니다.

여기서 반환되는 중간점의 값은 인덱스이므로 출력은 결과에서 +1한 값을 출력하면 됩니다.

profile
자기주도적, 지속 성장하는 모바일앱 개발자가 되기 위해

0개의 댓글

관련 채용 정보