알고리즘 개요 및 소개
깊이 우선 탐색(Depth First Search, BFS)은 *맹목적 탐색방법의 하나이다. 그래프에 여러 갈래의 길이 있는데 DFS, 의 이름이 의미하듯이 한 길을 깊이 파고드는 것이다.
*맹목적 탐색: 정해진 순서에 따라 상태 공간 그래프를 점차 형성해 가면서 해를 탐색하는 방법
시간 복잡도 |
O(|V|+|E|)) V: 정점의 수 E: 간선의 수 |
장점 |
- 목표 노드가 깊은 단계에 있을 경우 답을 빨리 구할 수 있다. - 저장공간이 적게 든다. |
단점 |
- 답이 없는 경로에 깊이 빠질 가능성이 있다. 미리 지정한 깊이만큼만 탐색하고 답이 없다면 다른 경로를 탐색하는 방법이 유용하다. - 얻은 답이 최단 경로라는 보장이 없다. |
탐색 과정
깊이 우선 탐색의 알고리즘은 다음과 같다.
- Stack 가장 상단 노드에 방문하지 않은 노드가 있으면 Push
- 방문하지 않은 노드가 없으면 pop
- 위 순서를 반복
1번 노드를 맨 처음 방문한다는 가정하에 시작을 하면 Stack에 1을 Push 한다.
2번 노드를 Stack에 Push 후 방문하지 않은 인접 노드들(4,5)을 Stack에 Push 한다.
더 이상 방문할 수 있는 인접 노드가 없기 때문에 Stack에서 데이터를 pop 한다.
1번 노드에 아직 방문하지 않은 3번 노드가 있기 때문에 3번 노드를 push 한다.
아직 방문하지 않는 노드들(6,7)을 방문 후 Stack에 Push 한다. 이후 인접한 노드들 중에 방문하지 않은 노드가 없기 때문에 모든 노드가 Stack에서 pop 후 종료된다.
소스코드
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
#include<iostream>
#include<queue>
#include<vector>
constexpr int MAX = 8;
class Graph {
private:
std::vector<int> node_[MAX];
bool is_visited_[MAX];
public:
Graph() {
for (int i = 0; i < MAX; ++i)
is_visited_[i] = false;
};
void InitNode() {
//1번 노드에 2,3을 넣음
node_[1].emplace_back(2);
node_[1].emplace_back(3);
//2번 노드에 1,4,5을 넣음
node_[2].emplace_back(1);
node_[2].emplace_back(4);
node_[2].emplace_back(5);
//3번 노드에 1,6,7을 넣음
node_[3].emplace_back(1);
node_[3].emplace_back(6);
node_[3].emplace_back(7);
//4번 노드에 2,5을 넣음
node_[4].emplace_back(2);
node_[4].emplace_back(5);
//5번 노드에 2,4를 넣음
node_[5].emplace_back(2);
node_[5].emplace_back(4);
//6번 노드에 3,7을 넣음
node_[6].emplace_back(3);
node_[6].emplace_back(7);
//7번 노드에 3,6을 넣음
node_[7].emplace_back(3);
node_[7].emplace_back(6);
}
void BFS(int started) {
std::queue<int> q;
q.push(started);
is_visited_[started] = true;
while (q.empty() == false) {
int curr = q.front();
q.pop();
std::cout << curr << " ";
for (int i = 0; i<node_[curr].size(); ++i) {
int node = node_[curr][i];
if (is_visited_[node] == false) {
q.push(node_[curr][i]);
is_visited_[node] = true;
}
}
}
}
void DFS(int started) {
//방문한 노드는 True
if (is_visited_[started] == false) {
is_visited_[started] = true;
std::cout << started << " ";
}
for (int i = 0; i < node_[started].size(); ++i) {
int node = node_[started][i];
if (is_visited_[node] == false) {
DFS(node);
}
}
return;
}
};
int main() {
Graph g;
g.InitNode();
g.DFS(1);
}
|
후기
너비 우선 탐색(Breadth First Search)에 이어서 두 번째 탐색 방식 DFS를 구현해보았다. 자료구조 Stack을tack] 간단한 Stack 구현을 사용하거나 재귀 함수를 사용해서 구현할 수 있다. 여기서는 후자로 구현을 하였다.
둘 중 하나의 방식에 익숙해진다면 나머지 하나의 방식은 크게 어렵지 않다.
출처 및 레퍼런스
Wiki: https://ko.wikipedia.org/wiki/깊이_우선_탐색
Book: 열혈 자료구조
그림: 본인
관련글
너비 우선 탐색(Breadth First Search)
20.04.21
코드-> Color Scripter, 폰트 및 색상 변경
'자료구조 알고리즘 > 탐색 알고리즘(Search)' 카테고리의 다른 글
[알고리즘] 다익스트라 알고리즘(Dijkstra algorithm) (0) | 2020.02.25 |
---|---|
[알고리즘] 합집합 찾기(Union-Find) (0) | 2020.02.14 |
[알고리즘] 최소 비용 신장 트리(Minimum Cost Spanning Tree) (0) | 2020.02.11 |
[알고리즘] 너비 우선 탐색(Breadth First Search) (0) | 2020.01.31 |
[알고리즘] 이진 탐색(Binary Search) (1) | 2020.01.12 |