알고리즘 개요 및 소개
너비 우선 탐색(Breadth First Search, BFS)은 *맹목적 탐색방법의 하나로 시작 정점을 방문한 후 시작 정점에 인접한 모든 정점들을 우선 방문하는 방법이다. 더 이상 방문하지 않은 정점이 없을 때까지 방문하지 않는 모든 정점들에 대해서도 너비 우선 탐색을 적용한다. 큐를 사용해야 레벨 순서대로 접근이 가능하다.
*맹목적 탐색: 정해진 순서에 따라 상태 공간 그래프를 점차 형성해 가면서 해를 탐색하는 방법
시간 복잡도 |
인접 리스트: O(|V|+|E|) 인접 행렬: O(|V|^2) V: 정점의 수 E: 간선의 수 |
장점 | 출발노드에서 목표노드까지의 최단 길이 경로를 보장한다. |
단점 |
- 경로가 매우 길 경우에는 탐색 가지가 급격히 증가함에 따라 보다 많은 기억 공간을 필요로 하게 된다. - 해가 존재하지 않는다면 유한 그래프의 경우에는 모든 그래프를 탐색한 후에 실패로 끝난다. - 무한 그래프의 경우에는 해를 찾지도 끝내지도 못한다. |
탐색 과정
너비 우선 탐색의 알고리즘은 다음과 같다.
- Queue에 가장 앞에 있는 노드를 pop
- POP 한 노드에 방문하지 않은 인접 노드를 모두 Queue에 Push
- Queue가 Empty 상태가 아니라면 위 순서를 반복
1번 노드를 맨 처음 방문한다는 가정하에 시작을 하면 Queue에 1을 Push 한다.
Queue에 가장 앞에 있는 1번 노드를 pop 한 후 1번 노드의 인접 노드 중 방문을 하지 않는 노드들(2번, 3번)을 모두 Queue에 Push 한다.
Queue에 가장 앞에 있는 2번 노드를 pop 한 후 2번 노드의 인접 노드 중 방문을 하지 않는 노드들(4번, 5번)을 모두 Queue에 Push 한다.
Queue에 가장 앞에 있는 3번 노드를 pop 한 후 3번 노드의 인접 노드 중 방문을 하지 않는 노드들(6번, 7번)을 모두 Queue에 Push 한다.
이후 더 이상 방문하지 않은 인접 노드가 없기 때문에 탐색은 종료가 된다.
소스코드
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
|
#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) {
}
};
int main() {
Graph g;
g.InitNode();
g.BFS(2);
}
|
후기
탐색의 방법 중 하나인 너비 우선 탐색(BFS)을 구현해 보았다. 알고리즘 시간에 다른 수업의 과제를 하다 보니 탐색 부분이 많이 약해서 걱정이었는데 트리나 그래프 등을 제대로 공부할 수 있는 시간이 된 거 같다. 아직 배워야 할 알고리즘도 많고 응용문제도 풀어봐야 하지만 차근차근할 예정이다.
출처 및 레퍼런스
Wiki: https://ko.wikipedia.org/wiki/너비_우선_탐색
그림: 본인
'자료구조 알고리즘 > 탐색 알고리즘(Search)' 카테고리의 다른 글
[알고리즘] 다익스트라 알고리즘(Dijkstra algorithm) (0) | 2020.02.25 |
---|---|
[알고리즘] 합집합 찾기(Union-Find) (0) | 2020.02.14 |
[알고리즘] 최소 비용 신장 트리(Minimum Cost Spanning Tree) (0) | 2020.02.11 |
[알고리즘] 깊이 우선 탐색(Depth First Search) (0) | 2020.02.03 |
[알고리즘] 이진 탐색(Binary Search) (1) | 2020.01.12 |