티스토리 뷰

Coding/Algorithm

DFS(깊이 우선 탐색).c

이끼대백과 2018. 2. 23. 16:34

DFS란 (Depth-First Search)라고 해요. 해석하자면 깊이를 우선해서 탐색한다?라고 할 수 있습니다. 무조건 한 우물만 판다는 얘기라고 생각할 수 있습니다.


천천히 한번 봐볼게요.


일단 이런 그래프가 있다고 가정하겠습니다. 모든 간선은 양방향입니다.

이 그래프를 DFS를 적용해서 탐색하는 순서는 작은 숫자를 먼저 탐색한다 하면 결과는 (1->2->3->4->5->4->6->4->3->2->1)입니다.

그림으로 순서를 보겠습니다.

먼저 1에 방문합니다. 그다음 1은 방문했다고 체크해둡니다. 1에서 갈 수 있는 곳은 2와 5입니다. 작은 수 먼저 탐색하기로 하였으니 다음은 2로 이동합니다.

2에 방문합니다. 2는 방문했다고 체크해두고, 2에서 갈 수 있는 곳은 1, 3, 4, 5인데요, 1은 아까 방문했으니 3, 4, 5중에 작은 3에 방문합니다.

3에 방문합니다. 3에 방문했다고 체크해두고, 3에서는 2, 4에 갈 수 있네요. 하지만 2에 이미 방문했으니 4로 갑니다!

4에 방문합니다. 4를 방문했다고 체크하고, 4에서는 2, 3, 5, 6을 갈 수 있네요. 2, 3은 이미 방문했으니 5, 6중에 작은 수인 5로 갑니다.

5에 방문합니다. 5에서는 1, 2, 4에 갈 수 있네요. 하지만 1, 2, 4모두 이미 방문했던 곳이므로 5 이전에 있었던 곳(4)으로 갑니다. 여기서 5에서 탐색은 끝난거죠.

다시 4로 와서, 아까 4에서는 2, 3, 5, 6을 갈 수 있었죠? 2, 3은 방문 했었기 때문에 못갔고 5는 탐색이 끝났으니 남은 6에 가야겠네요!

6에 방문하고, 방문했다고 체크해둡니다. 6에서는 4에 갈 수 있지만 이미 방문했으니 6에서도 탐색은 끝난겁니다! 따라서 전에 있던 곳(4)로 갑니다.

4로 돌아와서, 4에서는 2, 3, 5, 6에 갈 수 있었는데 2, 3은 이미 방문했고, 5, 6은 탐색이 끝났군요. 따라서 이전에 있던 곳(3)으로 갑니다. 여기서도 4에서의 탐색은 끝!!!

3으로 돌아와서, 아까 3에서는 2, 4에 갈 수 있었는데 2는 이미 방문했고, 4는 탐색이 끝났네요. 그렇다면 이전에 있던 곳(2)으로 갑니다. 3에서의 탐색은 끝.

2로 돌아와서, 아까 2에서는 1, 3, 4, 5에 갈 수 있었는데 1은 이미 방문했고, 3, 4, 5는 탐색이 끝났으니 여기서도 원래 있던 곳(1)으로 가야겠네요. 2에서의 탐색은 끝!

1로 돌아왔습니다. 1에서는 2, 5에 갈 수 있었는데, 두곳 모두 탐색이 끝났네요! 그리고 이전에 있던곳도 없으므로 탐색 종료!!

깊이 우선 탐색 끝!!



그림을 보면 탐색 도중에 탐색이 끝났으면 이전 곳으로 돌아가는 Backtracking이 발생합니다. 이것이 발생하면, 그곳에서는 탐색이 끝났다고 볼 수 있습니다.


이것을 C로 표현해보면

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
#include <stdio.h>
#include <stdbool.h>
#define MAX 1001
 
int Graph[MAX][MAX];
bool visited[MAX];
int N, M;
 
void dfs(int k) {
    visited[k] = true;
    for (int i = 1; i <= N; i++) {
        if (visited[i] != false || Graph[k][i] == 0continue;
        dfs(i);
    }
}
 
int main(void) {
 
    scanf("%d%d"&N,&M);
 
    for (int i = 0; i < M; i++) {
        int u, v;
        scanf("%d%d"&u, &v);
        Graph[u][v] = 1;
        Graph[v][u] = 1;
    }
    
    for (int i = 1; i <= N; i++) {
        if (!visited[i]) {
            dfs(i);
        }
    }
 
 
    return 0;
}
cs

이렇게 나타낼 수 있습니다. N은 정점 갯수(갈 수 있는곳 갯수) M은 간선 갯수(정점과 정점을 이어주는)입니다.

9:dfs함수는 정점을 주면 그정점에서 갈 수 있는 곳을 깊이 우선으로 탐색하는 함수입니다.

10:정점 k를 방문 했다고 체크합니다.

11:정점최대 갯수만큼 탐색을 해야겠죠?

12:이미 방문했거나, 정점 k->i의 길이 없다면 다른 정점을 찾아봅니다.

13:12번째 줄에 의해 발견된 정점 i로 탐색을 시작합니다.

24~25:설명한 그래프가 양방향이라서 1->2도 되고 2->1도 될 수 있게 했습니다 25번줄을 지우면 단방향 그래프가 되겠네요.



'Coding > Algorithm' 카테고리의 다른 글

최적화 문제 동적 계획법 레시피(종만북)  (0) 2020.03.31
What i learned!!!  (2) 2020.03.09
Tail Call Recursion  (0) 2019.02.19
정렬 간단한 정리  (0) 2018.10.24
Quick Sorting(퀵 정렬)  (0) 2018.04.08
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2025/01   »
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
글 보관함