DFS는 그래프나 트리를 탐색하는 알고리즘 중 하나로, 한 노드를 선택한 후 최대한 깊이 탐색한 후 다시 돌아오는 방식으로 작동한다. DFS는 재귀(recursion) 또는 스택(stack) 을 사용하여 구현할 수 있다.
print(root.value)
의 위치에 따라 트리 순회의 방식이 달라진다. DFS(깊이 우선 탐색) 알고리즘에서 트리 순회는 노드를 방문하는 순서에 따라 전위 순회(Pre-order)
, 중위 순회(In-order)
, 후위 순회(Post-order)
로 구분한다.
전위 순회는 노드 -> 왼쪽 자식 -> 오른쪽 자식
순으로 탐색한다. print(root.value)
를 노드를 먼저 방문하는 부분에 위치시킴
def pre_order_traversal(root):
if root is None:
return
print(root.value) # 노드를 먼저 방문
pre_order_traversal(root.left) # 왼쪽 자식 탐색
pre_order_traversal(root.right) # 오른쪽 자식 탐색
중위 순회는 왼쪽 자식 -> 노드 -> 오른쪽 자식
순으로 탐색한다. print(root.value)
는 왼쪽 자식을 모두 방문한 후, 현재 노드를 방문하는 부분에 위치함
def in_order_traversal(root):
if root is None:
return
in_order_traversal(root.left) # 왼쪽 자식 탐색
print(root.value) # 노드를 방문
in_order_traversal(root.right) # 오른쪽 자식 탐색
후위 순회는 왼쪽 자식 -> 오른쪽 자식 -> 노드 순
으로 탐색한다. print(root.value)
는 두 자식을 모두 방문한 후, 마지막에 노드를 방문하는 부분에 위치함
def post_order_traversal(root):
if root is None:
return
post_order_traversal(root.left) # 왼쪽 자식 탐색
post_order_traversal(root.right) # 오른쪽 자식 탐색
print(root.value) # 노드를 마지막에 방문
print(root.value)
는 자기 자신을 먼저 방문하는 시점에 넣는다.print(root.value)
는 왼쪽 자식 탐색 후 현재 노드를 방문하는 시점에 넣는다.print(root.value)
는 왼쪽, 오른쪽 자식 탐색 후 현재 노드를 방문하는 시점에 넣는다.즉, print(root.value)
가 트리를 탐색하는 순서에 중요한 영향을 미치며, 트리 순회 방법을 정의하는 핵심적인 부분이다.
def dfs_recursive(node, visited, graph):
"""DFS를 재귀 방식으로 구현"""
visited.add(node) # 현재 노드를 방문 처리
print(node, end=" ") # 방문한 노드 출력
for neighbor in graph[node]: # 현재 노드와 연결된 노드 탐색
if neighbor not in visited: # 방문하지 않은 노드라면 재귀 호출
dfs_recursive(neighbor, visited, graph)
# 그래프 예제 (인접 리스트 방식)
graph = {
0: [1, 2],
1: [0, 3, 4],
2: [0, 5, 6],
3: [1],
4: [1],
5: [2],
6: [2]
}
visited = set() # 방문한 노드를 저장할 집합
dfs_recursive(0, visited, graph) # 0번 노드에서 시작
def dfs_stack(start, graph):
"""DFS를 스택을 사용하여 구현"""
visited = set() # 방문한 노드를 저장할 집합
stack = [start] # 시작 노드를 스택에 추가
while stack: # 스택이 비어있지 않으면 계속 실행
node = stack.pop() # 스택에서 노드를 꺼냄
if node not in visited: # 방문하지 않았다면
visited.add(node) # 방문 처리
print(node, end=" ") # 방문한 노드 출력
# 인접 노드를 역순으로 스택에 추가 (순서 보장을 위해)
stack.extend(reversed(graph[node]))
# 그래프 예제 (인접 리스트 방식)
graph = {
0: [1, 2],
1: [0, 3, 4],
2: [0, 5, 6],
3: [1],
4: [1],
5: [2],
6: [2]
}
dfs_stack(0, graph) # 0번 노드에서 시작
DFS (깊이 우선 탐색) | BFS (너비 우선 탐색) |
---|---|
탐색 방식 | 한 방향으로 끝까지 탐색 후 백트래킹 |
자료 구조 | 스택(Stack) / 재귀(Recursion) |
특징 | 백트래킹에 유리, 경로 탐색 문제에 적합 |
시간 복잡도 | O(V + E) |
공간 복잡도 | O(V) (재귀 깊이) |