---
---
깊이 우선 탐색(Depth-First Search, DFS)을 잘 수행하려면 다음의 사고 단계를 따르는 것이 유용합니다:
1. 문제 이해
- 그래프 또는 트리 구조: 문제에서 주어진 데이터가 그래프나 트리 형태인지 확인합니다.
- 노드와 간선: 각 노드와 그 사이의 간선을 정의합니다.
2. 자료 구조 선택
- 그래프 표현: 인접 리스트(adjacency list)나 인접 행렬(adjacency matrix) 등 적절한 자료 구조를 선택합니다.
- 방문 여부 체크: 노드의 방문 여부를 체크할 자료 구조를 선택합니다. 보통 리스트나 집합(set)을 사용합니다.
3. DFS 동작 원리
- 재귀적 접근: DFS는 재귀적으로 구현하는 것이 일반적입니다. 이때 재귀 호출이 깊어질 수 있으므로 최대 재귀 깊이에 주의합니다.
- 스택 사용: 재귀를 사용하지 않고 명시적으로 스택을 이용하여 DFS를 구현할 수도 있습니다.
4. DFS 구현 단계
- 시작 노드 설정: 탐색을 시작할 노드를 선택합니다.
- 방문 표시: 현재 노드를 방문했음을 표시합니다.
- 인접 노드 탐색: 현재 노드의 인접 노드들을 순회하며 방문하지 않은 노드에 대해 DFS를 재귀적으로 호출합니다.
5. 코드 작성
- 재귀적 구현 예시:
def dfs_recursive(graph, start, visited=None):
if visited is None:
visited = set()
visited.add(start)
print(start) # 방문한 노드를 처리하는 부분
for neighbor in graph[start]:
if neighbor not in visited:
dfs_recursive(graph, neighbor, visited)
# 예시 그래프 (인접 리스트)
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
dfs_recursive(graph, 'A')
- 스택을 이용한 구현 예시:
def dfs_stack(graph, start):
visited = set()
stack = [start]
while stack:
node = stack.pop()
if node not in visited:
visited.add(node)
print(node) # 방문한 노드를 처리하는 부분
# 인접 노드들을 스택에 추가
stack.extend(neighbor for neighbor in graph[node] if neighbor not in visited)
# 예시 그래프 (인접 리스트)
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
dfs_stack(graph, 'A')
6. 검증 및 디버깅
- 출력 확인: DFS가 올바르게 동작하는지 확인하기 위해 출력 결과를 검증합니다.
- 경계 조건 처리: 예외 상황이나 경계 조건에 대한 처리가 필요한지 확인합니다.
이러한 단계들을 거쳐 DFS 알고리즘을 작성하면 효율적이고 정확하게 깊이 우선 탐색을 수행할 수 있습니다.