[알고리즘] DFS(깊이 우선 탐색),BFS(너비우선탐색)
DFS(깊이 우선 탐색)
필수 개념
- 스택: DFS는 일반적으로 스택 자료 구조를 사용하여 구현되며, 이는 재귀 호출을 통해 간접적으로 구현될 수도 있습니다.
- 재귀: DFS는 재귀적으로 호출하여 각 노드를 방문할 수 있습니다.
- 백트래킹: DFS는 탐색 중에 가능한 모든 경로를 탐색하고, 더 이상 진행할 수 없을 때 이전 단계로 돌아가는 방식입니다.
DFS의 기본 로직
- 초기화:
- 시작 노드를 지정하고, 방문 여부를 추적할 자료 구조를 초기화합니다. 보통 집합(set)이나 배열을 사용합니다.
- 탐색 시작:
- 시작 노드를 스택에 추가하거나, 재귀 함수를 호출합니다.
- 노드 방문:
- 현재 노드를 방문하고, 이 노드를 방문한 것으로 표시합니다.
- 인접 노드 탐색:
- 현재 노드와 인접한 노드를 스택에 추가하거나, 재귀 호출을 통해 방문합니다.
- 이미 방문한 노드는 다시 방문하지 않도록 합니다.
- 탐색 종료:
- 모든 노드를 방문했으면 탐색을 종료합니다.
def dfs(graph, start):
visited = set() # 방문한 노드를 추적
stack = [start] # 스택에 시작 노드 추가
while stack:
vertex = stack.pop() # 스택에서 노드 꺼내기
if vertex not in visited:
print(vertex) # 현재 노드 처리 (예: 출력)
visited.add(vertex) # 노드를 방문한 것으로 표시
stack.extend(graph[vertex] - visited) # 인접 노드를 스택에 추가
return visited
재귀사용
def dfs_recursive(graph, vertex, visited=None):
if visited is None:
visited = set()
visited.add(vertex)
print(vertex) # 현재 노드 처리 (예: 출력)
for neighbor in graph[vertex]:
if neighbor not in visited:
dfs_recursive(graph, neighbor, visited)
return visited
BFS(너비 우선 탐색)
필수 개념
- 큐: BFS는 큐 자료 구조를 사용하여 구현됩니다. 이는 FIFO(First In First Out) 방식으로 작동합니다.
- 레벨 순서 탐색: BFS는 시작 노드에서부터 인접한 노드를 차례로 탐색하며, 각 노드를 레벨 순서로 방문합니다
필수 지식
- 그래프 표현: 그래프를 인접 리스트 또는 인접 행렬로 표현할 수 있어야 합니다.
- 방문 여부 확인: 노드가 이미 방문되었는지 확인하기 위해 방문 배열이나 집합을 사용할 수 있습니다.
- 큐 사용법: 파이썬의 collections.deque를 사용하여 큐를 효과적으로 구현할 수 있습니다.
DFS와 BFS의 비교
BFS의 기본 로직
- 초기화:
- 시작 노드를 지정하고, 방문 여부를 추적할 자료 구조를 초기화합니다. 큐를 사용합니다.
- 탐색 시작:
- 시작 노드를 큐에 추가하고, 방문 여부를 추적합니다.
- 노드 방문:
- 큐에서 노드를 꺼내고, 이 노드를 방문한 것으로 표시합니다.
- 인접 노드 탐색:
- 현재 노드와 인접한 노드를 큐에 추가합니다. 큐에 추가하기 전에 해당 노드가 이미 방문되었는지 확인합니다.
- 탐색 종료:
from collections import deque
def bfs(graph, start):
visited = set() # 방문한 노드를 추적
queue = deque([start]) # 큐에 시작 노드 추가
visited.add(start) # 시작 노드를 방문한 것으로 표시
while queue:
vertex = queue.popleft() # 큐에서 노드 꺼내기
print(vertex) # 현재 노드 처리 (예: 출력)
for neighbor in graph[vertex]:
if neighbor not in visited:
visited.add(neighbor) # 노드를 방문한 것으로 표시
queue.append(neighbor) # 인접 노드를 큐에 추가
return visited
코드 작성 시 고려할 점
- 그래프 표현:
- 그래프를 어떻게 표현할 것인지 결정합니다 (인접 리스트 또는 인접 행렬).
- 방문 여부 확인:
- 노드가 이미 방문되었는지 확인하고, 중복 방문을 방지합니다.
- 자료 구조 선택:
- DFS: 스택 또는 재귀
- BFS: 큐
- 기본 작업 처리:
- 노드를 방문할 때 해야 할 기본 작업 (예: 출력, 결과 저장 등)을 정의합니다.
- 기저 조건 설정:
- DFS에서는 재귀 호출의 종료 조건을 설정하고, BFS에서는 큐가 비어 있을 때까지 탐색을 계속합니다.
블로그의 정보
개발 블로그👩💻
Blairj