리스트 내에서 데이터를 매우 빠르게 탐색하는 이진 탐색 알고리즘에 대해서 공부해보자.
이진 탐색을 공부하기 전에 순차 탐색에 대해 먼저 이해할 필요가 있다.
순차 탐색(Sequential Search): 리스트 안에 있는 특정한 데이터를 찾기 위해 앞에서부터 데이터를 하나씩 확인하는 방법으로 보통 정렬되지 않은 리스트에서 데이터를 찾아야 할 때 사용한다. 리스트 내에 데이터가 아무리 많아도 시간만 충분하다면 항상 원하는 원소를 찾을 수 있다는 장점이 있다.
순차 탐색의 경우 데이터의 개수가 N일 때, 최악의 경우 시간 복잡도가 O(N)이다.
이진탐색(Binary Search): 배열 내부의 데이터가 정렬되어 있어야만 사용할 수 있는 알고리즘이다. 데이터가 무작위일 때는 사용할 수 없지만, 이미 정렬되어 있자면 매우 빠르게 데이터를 찾을 수 있다.
이진 탐색은 위치를 나타내는 변수 3개를 사용하는 데 탐색하고자 하는 범위의 시작점, 끝점, 중간점이 있다. 찾으려는 데이터와 중간점 위치에 있는 데이터를 반복적으로 비교해서 원하는 데이터를 찾는 것이 이진 탐색의 과정이다.
이진 탐색의 시간 복잡도는 O(logN)이 된다.
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 = map(int, input().split())
array = list(map(int, input().split()))
result = binary_search(array, target, 0, n-1)
if result== "None":
print("not found")
else:
print(result+1)
#반복문을 이용한 이진 탐색
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 = map(int, input().split())
array = list(map(int, input().split()))
result = binary_search(array, target, 0, n-1)
if result== None:
print("not found")
else:
print(result+1)
이진 탐색은 전제 조건이 데이터 정렬이다. 예를 들어 프로그램에서 데이터를 정렬해두는 경우가 많으므로 이진 탐색을 효과적으로 사용할 수 있다. 데이터베이스는 내부적으로 대용량 데이터 처리에 적합한 트리 자료구조를 이용하여 항상 데이터가 정렬되어 있다. 따라서 DB에서의 탐색은 이진 탐색과는 조금 다르지만 이진 탐색과 유사한 방법을 이용해 탐색을 항상 빠르게 수행하도록 설계되어 있어서 데이터가 많아도 탐색하는 속도가 빠르다.
트리 구조가 무엇인지 알아보자.
트리 자료구조는 노드와 노드의 연결로 표현하며 여기에는 노드의 정보의 단위로서 어떠한 정보를 가지고 있는 개체로 이해할 수 있다. 5장에서 그래프를 다룰 때 언급했던 노드와 동일하다. 최단 경로에서는 노드가 ‘도시’와 같은 정점의 의미를 가진다고 하였다. 트리 자료구조는 그래프 자료구조의 일종으로 데이터베이스 시스템이나 파일 시스템과 같은 곳에서 많은 양의 데이터를 관리하기 위한 목적으로 사용한다. 트리 자료구조는 몇가지 주요한 특징이 있다.