탐색 알고리즘은 컴퓨터 과학에서 특정 데이터 항목을 데이터 구조 내에서 찾거나, 문제 해결을 위한 최적의 경로를 찾는 데 사용되는 핵심적인 방법론입니다. 효율적인 탐색 알고리즘의 선택은 프로그램의 성능과 자원 활용에 지대한 영향을 미치므로, 각 알고리즘의 특성과 적용 분야를 이해하는 것이 중요합니다.
데이터 집합의 처음부터 끝까지 순차적으로 모든 요소를 확인하여 원하는 값을 찾는 가장 기본적인 탐색 방법입니다. 데이터가 정렬되어 있지 않아도 적용 가능하며, 구현이 매우 간단합니다. 하지만 데이터의 크기가 커질수록 효율성이 떨어집니다 (최악의 경우 O(n)).
def linear_search(arr, target):
for i in range(len(arr)):
if arr[i] == target:
return i
return -1
if __name__ == "__main__":
data = [4, 2, 7, 1, 9, 5, 3, 8, 6]
target_found = 5
target_not_found = 10
print(f"데이터: {data}")
print(f"타겟 {target_found} (선형 탐색): {linear_search(data, target_found)}")
print(f"타겟 {target_not_found} (선형 탐색): {linear_search(data, target_not_found)}")
선형 탐색이 데이터를 순차적으로 확인하는 과정을 보여줍니다.
정렬된 데이터 집합에서 중앙값을 기준으로 탐색 범위를 절반씩 줄여나가며 원하는 값을 찾는 방법입니다. 반드시 데이터가 정렬되어 있어야 하며, 시간 복잡도는 O(log n)으로 선형 탐색보다 훨씬 효율적입니다. 대량의 정렬된 데이터에서 빠른 탐색이 가능합니다.
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
if __name__ == "__main__":
data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
target_found = 5
target_not_found = 10
print(f"데이터: {data}")
print(f"타겟 {target_found} (이진 탐색): {binary_search(data, target_found)}")
print(f"타겟 {target_not_found} (이진 탐색): {binary_search(data, target_not_found)}")
이진 탐색이 탐색 범위를 절반씩 줄여나가는 과정을 보여줍니다.
그래프나 트리에서 한 경로를 가능한 한 깊이 탐색한 후, 더 이상 탐색할 경로가 없으면 되돌아와 다른 경로를 탐색하는 방법입니다. 스택(Stack) 또는 재귀 함수를 사용하여 구현되며, 미로 찾기, 연결된 요소 찾기 등에 활용됩니다.
def dfs(graph, start_node):
visited = []
stack = [start_node]
while stack:
node = stack.pop()
if node not in visited:
visited.append(node)
if node in graph:
for neighbor in sorted(graph[node], reverse=True):
stack.append(neighbor)
return visited
if __name__ == "__main__":
graph = {
'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F'],
'D': [],
'E': ['F'],
'F': []
}
print(f"그래프: {graph}")
print(f"DFS 탐색 결과 (시작 노드 A): {dfs(graph, 'A')}")
깊이 우선 탐색이 노드를 방문하는 과정을 보여줍니다.
그래프나 트리에서 시작 노드로부터 가까운 노드부터 차례대로 탐색하는 방법입니다. 큐(Queue)를 사용하여 구현되며, 최단 경로를 찾는 데 유용합니다 (간선의 가중치가 동일할 경우). 소셜 네트워크에서 친구 관계 탐색, 최단 경로 찾기 등에 활용됩니다.
from collections import deque
def bfs(graph, start_node):
visited = []
queue = deque([start_node])
while queue:
node = queue.popleft()
if node not in visited:
visited.append(node)
if node in graph:
for neighbor in sorted(graph[node]):
queue.append(neighbor)
return visited
if __name__ == "__main__":
graph = {
'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F'],
'D': [],
'E': ['F'],
'F': []
}
print(f"그래프: {graph}")
print(f"BFS 탐색 결과 (시작 노드 A): {bfs(graph, 'A')}")
너비 우선 탐색이 노드를 방문하는 과정을 보여줍니다.