[그래프] 깊이 우선 탐색 DFS
2024. 9. 14. 21:49ㆍ알고리즘 & 자료구조/그래프
DFS
DFS는 그래프나 트리에서 탐색하는 알고리즘 중 하나로, 시작점에서부터 가능한 깊은 곳까지 탐색한 후에 백트래킹(backtracking)하여 다른 경로를 탐색하는 방식입니다. 즉, 한 경로를 따라 최대한 깊게 탐색한 후, 더 이상 탐색할 노드가 없으면 이전 노드로 돌아가 다른 경로를 탐색합니다.
특징
- 깊이 우선 탐색: DFS는 가능한 한 깊은 노드까지 탐색한 후, 더 이상 내려갈 수 없을 때 돌아가서 다른 경로를 탐색합니다. 노드를 "깊이"를 기준으로 탐색합니다.
- 스택(Stack)을 이용한 구현: DFS는 노드를 저장하고 탐색 순서를 관리하기 위해 스택 자료 구조를 사용합니다. 현재 노드에서 인접한 노드를 스택에 추가하고, 가장 나중에 추가된 노드부터 처리합니다(LIFO, Last In, First Out 방식).
- 백트래킹: 깊이 우선 탐색은 탐색 도중 더 이상 진행할 수 없는 경우, 이전의 상태로 돌아가 다른 경로를 탐색합니다. 이 과정을 백트래킹이라고 합니다.
- 재귀적 구현: DFS는 재귀적으로 구현될 수 있습니다. 노드를 탐색할 때, 인접 노드를 재귀 호출하여 탐색합니다.
장단점
- 장점:
- 공간 복잡도가 BFS보다 낮을 수 있습니다. DFS는 스택(혹은 재귀 호출)을 사용하므로 큐에 비해 더 적은 공간을 필요로 할 수 있습니다.
- 경로가 매우 깊은 경우에도 유용합니다.
- 단점:
- 최단 경로를 보장하지 않습니다. 깊이 우선 탐색은 최단 경로를 찾는 데 적합하지 않습니다.
- 사이클이 있는 그래프에서 무한 루프에 빠질 수 있으며, 이를 방지하기 위해 방문한 노드를 추적해야 합니다.
시간 및 공간 복잡도
- 시간 복잡도: O(V+E)O(V + E) (V는 정점의 수, E는 간선의 수)
- 각 노드를 한 번씩 방문하고, 각 간선을 한 번씩 처리하기 때문입니다.
- 공간 복잡도: O(V)O(V)
- 스택 또는 재귀 호출에 의해 모든 노드를 저장할 필요가 있습니다.
의사 코드 + Java 코드
DFS(graph, startNode):
1. 스택(Stack) 생성
2. 방문 여부를 기록할 리스트 또는 배열 생성
3. 시작 노드를 스택에 추가하고 방문 처리
4. 스택이 빌 때까지 다음을 반복:
a. 스택에서 노드를 하나 꺼냄
b. 해당 노드의 모든 인접 노드를 확인
c. 방문하지 않은 인접 노드를 스택에 추가하고 방문 처리
import java.util.*;
public class GraphTraversal {
private Map<Integer, List<Integer>> graph;
public GraphTraversal(Map<Integer, List<Integer>> graph) {
this.graph = graph;
}
public void dfs(int startNode) {
// 방문한 노드를 기록하기 위한 집합
Set<Integer> visited = new HashSet<>();
// DFS에 사용할 스택
Stack<Integer> stack = new Stack<>();
// 시작 노드를 스택에 넣고 방문 표시
stack.push(startNode);
visited.add(startNode);
while (!stack.isEmpty()) {
// 스택에서 노드를 꺼내서 처리
int currentNode = stack.pop();
System.out.println("Visited node: " + currentNode);
// 현재 노드의 이웃들을 확인
List<Integer> neighbors = graph.getOrDefault(currentNode, new ArrayList<>());
for (int neighbor : neighbors) {
if (!visited.contains(neighbor)) {
stack.push(neighbor);
visited.add(neighbor);
}
}
}
}
}
DFS의 활용 예시
- 경로 찾기: 특정 노드에서 다른 노드로 가는 경로를 찾을 때 유용합니다.
- 연결성 검사: 그래프가 연결되어 있는지 확인하는 데 사용합니다.
- 그래프의 사이클 탐지: 사이클이 있는지 확인하는 데 사용할 수 있습니다.
- 토폴로지 정렬: 방향 그래프에서 정렬을 수행할 때 DFS를 사용할 수 있습니다.
'알고리즘 & 자료구조 > 그래프' 카테고리의 다른 글
[그래프] 너비 우선 탐색 BFS (3) | 2024.09.13 |
---|