코드잇의 알고리즘의 정석 수업을 수강하고 정리한 글입니다.
로미오와 줄리엣 책을 찾고자 한다. 어떤 방법이 좋을까?
다양한 방법들을 고민하고 어떤 방법이 좋을지 분석하는것이 알고리즘 공부이다.
우리는 도서관의 책을 찾는 법을 살펴보았다. 이러한 문제를 프로그래밍에서는 "탐색 문제"라고 한다.
탐색 : 저장된 정보들 중에서 원하는 값을 찾는 것
선형 탐색 알고리즘과 이진 탐색 알고리즘을 이용해 탐색을 수행해보자.
우리는 같은 문제를 풀었는데 두가지 해결책을 찾아내었다. 어떤 방법이 효율적일지 고민해보자.
'선형 탐색(Linear Search)' 알고리즘을 사용해서 어떤 원소가 리스트안에 포함되어있는지 확인하라.
파라미터로 입력되는 element, some_list는 탐색할 값과 검색할 리스트이다.
element를 찾으면 그 위치(인덱스)를 리턴하고 존재하지 않으면 None을 리턴하라.
# 구현 코드
def linear_search(element, some_list):
pass
print(linear_search(2, [2, 3, 5, 7, 11]))
print(linear_search(0, [2, 3, 5, 7, 11]))
print(linear_search(5, [2, 3, 5, 7, 11]))
print(linear_search(3, [2, 3, 5, 7, 11]))
print(linear_search(11, [2, 3, 5, 7, 11]))
# 실행 결과
0
None
2
1
4
# 구현 코드
def linear_search(element, some_list):
for i in range(len(some_list)):
if some_list[i] == element:
return i
print(linear_search(2, [2, 3, 5, 7, 11]))
print(linear_search(0, [2, 3, 5, 7, 11]))
print(linear_search(5, [2, 3, 5, 7, 11]))
print(linear_search(3, [2, 3, 5, 7, 11]))
print(linear_search(11, [2, 3, 5, 7, 11]))
for문을 이용해서 some_list로부터 element를 탐색하도록 하였고, 함수가 끝났을 때 return을 명시해주지 않으면 None을 반환하므로 return은 따로 명시하지 않았다.
'이진 탐색(Binary Search)' 알고리즘을 사용해서 어떤 원소가 리스트 안에 포함되었는지 확인하라.
이진 탐색은 정렬된 리스트를 전제로 한다. (그래야만 적용이 가능하다.)
element를 찾으면 그 위치(인덱스)를 리턴하고 존재하지 않으면 None을 리턴하라.
# 구현 코드
def binary_search(element, some_list):
pass
print(binary_search(2, [2, 3, 5, 7, 11]))
print(binary_search(0, [2, 3, 5, 7, 11]))
print(binary_search(5, [2, 3, 5, 7, 11]))
print(binary_search(3, [2, 3, 5, 7, 11]))
print(binary_search(11, [2, 3, 5, 7, 11]))
# 실행 결과
0
None
2
1
4
def binary_search(element, some_list):
left = 0
right = len(some_list)-1
while True:
if left>right: # 시작, 끝 인덱스가 역전되면 None을 반환
return None
center = (left + right) // 2 # 중간값에 대한 인덱스 구하기
if some_list[center] == element: # element를 찾았으면 반환
return center
if element > some_list[center]: # 중간값보다 element가 크면 왼쪽은 제외
left = center + 1
else: # 중간값보다 element가 작으면 오른쪽은 제외
right = center - 1
print(binary_search(2, [2, 3, 5, 7, 11]))
print(binary_search(0, [2, 3, 5, 7, 11]))
print(binary_search(5, [2, 3, 5, 7, 11]))
print(binary_search(3, [2, 3, 5, 7, 11]))
print(binary_search(11, [2, 3, 5, 7, 11]))
def binary_search(element, some_list):
start_index = 0
end_index = len(some_list) - 1
while start_index <= end_index: # while문의 반복 조건으로 시작 인덱스와 마지막 인덱스가 역전되지 않았을 때만 동작
midpoint = (start_index + end_index) // 2
if some_list[midpoint] == element:
return midpoint
elif some_list[midpoint] > element:
end_index = midpoint - 1
else:
start_index = midpoint + 1
return None
print(binary_search(2, [2, 3, 5, 7, 11]))
print(binary_search(0, [2, 3, 5, 7, 11]))
print(binary_search(5, [2, 3, 5, 7, 11]))
print(binary_search(3, [2, 3, 5, 7, 11]))
print(binary_search(11, [2, 3, 5, 7, 11]))
-> while문의 반복 조건으로 시작 인덱스와 마지막 인덱스가 역전되지 않았을 때만 동작하도록 하였다. 이를 통해 반복문 내의 코드가 줄었다.