[C] 자료구조 / DFS / 깊이 우선 탐색 / DepthFirstSearch.

2020. 7. 24. 15:39🧑🏻‍💻/C & 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
#include<stdio.h>
 
int AdjacencyMatrix[10][10]; //행렬 여부 체크
int Visited[9];                 //방문 여부 체크 
 
void DepthFirstSearch(int v) {
    Visited[v] = 1;             //방문 처리
    //printf("%d ", v);         //방문 표시
    for (int i = 0;i < 10;i++) {
        if (!Visited[i] && AdjacencyMatrix[v][i]) { // 방문하지 않았고, 인접 행렬일 경우.
            printf("    Tracking %d -> %d\n",v,i);
            DepthFirstSearch(i);                    // 재귀함수
            printf("BackTracking'%d => %d'\n",i,v);
        }
    }
}
 
int main(void) {
    int i, x, y;
    for (i = 0;i < 10;i++) {                        //10개의 Edge. 그래프를 만드는 과정 
        scanf("%d %d"&x, &y);
        AdjacencyMatrix[x][y] = AdjacencyMatrix[y][x] = 1;
        //인접행렬을 만들어주는 Line
    }
    //printf("방문 순서 : ");
    DepthFirstSearch(0);
}
DepthFirstSearch

깊이 우선 탐색 맹목적 탐색방법의 하나로 탐색트리의 최근에 첨가된 노드를 선택하고,
이 노드에 적용 가능한 동작자 중 하나를 적용하여 트리에 다음 수준(level)의 한 개의 자식노드를 첨가하며,
첨가된 자식 노드가 목표노드일 때까지 앞의 자식 노드의 첨가 과정을 반복해 가는 방식이다.

탐색 과정이 시작 노드에서 한없이 깊이 진행되는 것을 막기 위해 깊이 제한(depth bound)을 사용한다.
깊이 제한에 도달할 때까지 목표노드가 발견되지 않으면 최근에 첨가된 노드의 부모노드로 되돌아와서,
부모노드에 이전과는 다른 동작자를 적용하여 새로운 자식노드를 생성한다.

여기서 부모노드로 되돌아오는 과정을 백트래킹(backtracking)이라 한다.

 

알고리즘
만일 트리가 아닌 그래프를 탐색하게 된다면 약간의 변화가 필요하다.

우선 그래프에서의 깊이(depth)를 결정할 필요가 있다. 일반적으로 그래프에서는 루트 노드의 깊이를 0으로 하며,
임의의 노드의 깊이는 이의 부모 중 가장 깊이가 작은 것의 깊이에 1을 더한 값으로 정의한다.
따라서 그래프에서의 깊이우선탐색은 OPEN에 있는 노드 중 가장 깊은 것을 택하여 확장시키게 된다.
후계 노드가 생성되어 이 중에 이미 OPEN이나 CLOSED에 있는 것이 있다면, 깊이를 재조정하여야 한다.

여기서 알 수 있는 것은 일반적인 그래프를 탐색하는 경우라도,
탐색 과정에 의하여 얻어지는 노드들과 포인터들은 역시 탐색 트리를 형성한다는 것이다.
즉, 포인터들은 오직 하나의 부모를 가리키게 된다.