728x90
반응형
깊이 우선 탐색(DFS)
루트 노드(혹은 다른 임의의 노드)에서 시작해서 다음 분기로 넘어가기 전에 해당 분기를 완벽하게 탐색하는 방법이다.
- 미로를 탐색할 때 한 방향으로 계속 가다가 더 이상 갈 수 없게 되면 다시 가까운 갈림길로 돌아와 이곳부터 다른 방향으로 다시 탐색을 진행하는 방법과 유사하다.
- 그래프에서 모든 노드를 방문하고자 할 때 더 선호되는 편이다.
- 전위 순회를 포함한 다른 형태의 트리 순회는 모두 깊이 우선 탐색의 한 종류이다.
- 그래프 탐색의 경우 어떤 노드를 방문했었는지 여부를 반드시 검사해야한다.(안하면 무한 루프에 빠질 위험 있음)
- 깊이 우선 탐색은 자기 자신을 다시 호출하는 순환 알고리즘의 형태를 가지고 있다.
A //시작 노드
/ \
B C //A와 연결된 노드
| |
D E //각 B, C와 연결된 노드
우선 위의 그래프를 스텍을 이용해 DFS를 구현해 보자
Stack: [A]
Visited: []
시작 노드 A를 스택에 넣고 방문한다.
스택에서 노드를 하나 꺼내고, 해당 노드와 연결된 방문하지 않은 노드를 스택에 넣는다.
이때, 가능한 깊이 들어가서 탐색한다.
Stack: [B, C]
Visited: [A]
B를 꺼내 방문한다. B와 연결된 노드 D가 들어간다.
Stack: [D, C]
Visited: [A, B]
D를 꺼내 방문한다.
D는 더 이상 연결된 노드가 없으므로 스택에서 C가 꺼내진다.
C와 연결된 노드 E가 스택에 들어간다.
Stack: [E]
Visited: [A, B, D, C]
마지막으로 E를 꺼내 방문한다.
스택에서 노드가 모두 꺼내지면서 DFS 탐색이 완료된다.
깊이 우선 탐색의 구현
//스택을 이용
import java.util.*;
class Graph {
private int V; // 그래프의 노드 수
private LinkedList<Integer> adjList[]; // 인접 리스트
Graph(int v) {
V = v;
adjList = new LinkedList[v];
for (int i = 0; i < v; i++) {
adjList[i] = new LinkedList<>();
}
}
// 그래프에 간선 추가
void addEdge(int v, int w) {
adjList[v].add(w);
}
// DFS 시작
void DFS(int start) {
boolean visited[] = new boolean[V]; //방문했으면 true
Stack<Integer> stack = new Stack<>();
stack.push(start); // 시작 노드를 스택에 넣음
while (!stack.isEmpty()) {
int current = stack.pop();
if (!visited[current]) {
visited[current] = true;
System.out.print(current + " ");
for (Integer neighbor : adjList[current]) {
if (!visited[neighbor]) {
stack.push(neighbor);
}
}
}
}
}
public static void main(String[] args) {
Graph graph = new Graph(5);
graph.addEdge(0, 1);
graph.addEdge(0, 2);
graph.addEdge(1, 3);
graph.addEdge(2, 4);
System.out.println("DFS starting from vertex 0:");
graph.DFS(0);
}
}
//재귀 함수를 이용
import java.util.*;
class Graph {
private int V; // 그래프의 노드 수
private LinkedList<Integer> adjList[]; // 인접 리스트
Graph(int v) {
V = v;
adjList = new LinkedList[v];
for (int i = 0; i < v; i++) {
adjList[i] = new LinkedList<>();
}
}
// 그래프에 간선 추가
void addEdge(int v, int w) {
adjList[v].add(w);
}
// DFS 탐색
void DFS(int v, boolean visited[]) {
visited[v] = true;
System.out.print(v + " ");
for (Integer neighbor : adjList[v]) {
if (!visited[neighbor]) {
DFS(neighbor, visited);
}
}
}
// DFS 시작
void DFS(int start) {
boolean visited[] = new boolean[V];
DFS(start, visited);
}
public static void main(String[] args) {
Graph graph = new Graph(5);
graph.addEdge(0, 1);
graph.addEdge(0, 2);
graph.addEdge(1, 3);
graph.addEdge(2, 4);
System.out.println("DFS starting from vertex 0:");
graph.DFS(0);
}
}728x90
반응형
'Algorithm > 알고리즘' 카테고리의 다른 글
| [ 백트래킹 ] N과 M (0) | 2025.10.26 |
|---|---|
| [Java / Javascript] HashSet, HashMap (0) | 2024.03.13 |
| [ 프로그래머스 / Java ] 1차 캐시 (0) | 2024.01.09 |
| 스택(Stack) (0) | 2023.11.03 |
| 선형 검색과 이진 검색 (1) | 2023.11.01 |