깊이 우선 탐색(DFS)
한 경로를 끝까지 탐색한 후 다른 경로를 탐색하는 알고리즘.
주로 스택 혹은 재귀함수를 사용합니다.
특징
- 메모리 사용이 적음
- 목표 노드가 깊은 단계에 있을 때 유리
- 모든 노드를 방문하고자 할 때 적합합니다.
사용 사례
- 미로 찾기
- 위상 정렬
- 사이클 탐지
예시 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import java.util.*;
class Graph {
private int V; // 노드의 수
private LinkedList<Integer>[] adj; // 인접 리스트
// 생성자
Graph(int v) {
V = v;
adj = new LinkedList[v];
for (int i = 0; i < v; ++i)
adj[i] = new LinkedList();
}
// 간선 추가
void addEdge(int v, int w) {
adj[v].add(w);
}
// DFS를 위한 재귀 함수
void DFSUtil(int v, boolean visited[]) {
// 현재 노드를 방문한 것으로 표시하고 출력
visited[v] = true;
System.out.print(v + " ");
// 방문한 노드와 인접한 모든 노드를 가져온다
Iterator<Integer> i = adj[v].listIterator();
while (i.hasNext()) {
int n = i.next();
// 방문하지 않은 노드면 해당 노드를 시작 노드로 다시 DFSUtil 호출
if (!visited[n])
DFSUtil(n, visited);
}
}
// 주어진 노드를 시작 노드로 DFS 탐색
void DFS(int v) {
// 노드의 방문 여부 판단 (초깃값: false)
boolean visited[] = new boolean[V];
// v를 시작 노드로 DFSUtil 재귀 호출
DFSUtil(v, visited);
}
// 메인 메서드
public static void main(String args[]) {
Graph g = new Graph(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
System.out.println("주어진 정점 2에서 시작한 깊이 우선 탐색");
g.DFS(2);
}
}
각 부분 설명
Graph클래스- 그래프를 표현하며, 노드의 수(
V)와 인접 리스트(adj)를 가집니다. addEdge메소드로 그래프에 간선을 추가할 수 있습니다.
- 그래프를 표현하며, 노드의 수(
DFSUtil메소드- DFS 알고리즘을 구현한 재귀 메소드입니다.
- 현재 노드를 방문 처리하고, 인접한 노드들을 확인합니다.
- 방문하지 않은 인접 노드가 있으면, 그 노드에 대해 재귀적으로
DFSUtil을 호출합니다.
DFS메소드- DFS 탐색을 시작하는 메소드입니다.
- 방문 여부를 체크할 배열을 초기화하고,
DFSUtil을 호출합니다.
동작 방식
- 시작 노드를 방문 처리
- 시작 노드의 인접 노드중 방문하지 않은 노드를 선택
- 선택한 노드에 대해 재귀적으로 1-2과정을 반복
- 더 이상 방문할 인접 노드가 없으면 이전 노드로 돌아감
- 모든 노드를 방문할 때까지 2-4 과정을 반복
시간 복잡도는 O(V + E)이다. V는 노드의 수, E는 간선의 수이다.
このポストは作成者の CC BY 4.0 ライセンスによって保護されます。