2024년 2월 19일
DFS
는 깊이 우선 탐색이라고 하고 말그대로 깊이를 우선적으로 탐색하는 알고리즘이다.
깊이 우선 탐색이라는 것은 루트 노드에서 시작해서, 다음 분기로 넘어가기전에 해당 분기를 완벽하게 탐색하는 방법이다.
0, 1, 2, 3, 4
라는 노드가 있다고 가정했을때, 0부터 시작해서 갈수 있는 한 최대한 깊이 이동한다. (위의 예는 0,1,2,3,4 일 것이다)
만약 갈수 있는 최대한의 깊이로 이동해서 더이상 갈수 없다면, 바로 그 전의 노드로 이동한다 (3으로 백트래킹)
그 전의 노드로 돌아와서, 해당 노드의 다른 방향으로 더 깊이 갈수 있는 노드는 없는지 탐색한다.
또 없다면 다시 그 전의 노드로 백트래킹 (2번 노드로 회귀)해서 또 반복해서 탐색해준다.
보통 넓이를 우선적으로 탐색하는 BFS
보다 속도 자체는 느리지만, BFS보다 구현하기에 편리하므로 사용하는 경우가 많다. (재귀함수 또한 스택과 동일한 동작 원리를 가지기 때문이다.)
모든 노드를 방문 해주어야 하는 경우에 DFS를 사용한다.
자기 자신을 호출하는 재귀적 흐름의 형태를 띄고 있으며, stack
자료구조를 사용하여 구현한다.
위의 사진처럼 그래프가 이루어져있고, dfs 탐색을 한다고 가정해보자.
그래프 문제에서 정점
과 간선
이라는 용어가 등장하는데, 정점은 각 노드, 간선은 노드와 노드를 이어주는 선이라고 생각하면 된다.
let graph = [[], [2, 3, 4], [1], [1, 5, 6], [1, 7], [3, 8], [3], [4], [5]]; // 0번은 제외
let visited = Array(9).fill(false);
function dfs(graph, v, visited) {
visited[v] = true; // 현재 노드를 방문 처리 해준다.
console.log(v);
// 현재 노드와 연결된 다른 노드를 재귀적으로 방문
for (let i of graph[v]) {
if (!visited[i]) {
dfs(graph, i, visited);
}
}
}
dfs(graph, 1, visited);
문제 내에서 0번이 아니라 1번부터 탐색을 해야하는것이라면, 아예 0번 인덱스에 빈배열을 넣어줌으로써 간편성을 더할수 있다. (방문 처리 배열 또한 N+1으로 해준다.)