DFS 설명 보려면 이전 글을 참고하자
BFS(Breadth-First Search) 는 DFS와 더불어 그래프에서 많이 사용하는 알고리즘이다.
체감상 DFS보다 BFS를 사용하는 문제를 더 많이 접하게 되는 것 같다.
DFS와 마찬가지로 BFS 알고리즘은 한 노드에서 출발해 연결된 모든 노드들을 방문하게 된다.
하지만 DFS가 가능한 한 깊게 탐색하고 되돌아 오는 것에 반해 BFS는 가까운 모든 노드들을 먼저 방문한 후 깊이 들어가게 된다.
BFS 알고리즘이 어떻게 작동하는지 살펴보자
BFS는 큐(Queue) 자료구조를 사용해서 구현한다
DFS를 설명했던 노드 그림을 그대로 가져와서 설명해 보도록 하겠다.
시작 노드는 0으로 설정하였다.
Queue : [0]
Queue : [1, 2]
2. 시작 노드 방문
3. 인접노드 큐에 추가
큐에서 시작노드 0을 뺀 후 0과 연결되어 있는 모든 노드들을 큐에 추가한다.
여기서는 1, 2가 연결되어 있기 때문에 queue에는 0, 1이 들어가게 된다.
4. 큐에 없어질때까지 반복
노드 1 방문
Queue : [2, 3]
큐는 FIFO로 먼저들어간 1이 먼저 나오게 된다.
1을 방문한 후 1과 연결된 노드들을 모두 추가해 준다.
여기서는 3이 있기 때문에 큐에 3을 넣어 준다.
노드 2 방문
Queue : [3, 4, 5]
큐의 제일 앞에 있는 2를 빼서 방문한다.
2와 연결되어 있는 노드들을 모두 큐에 넣는다.
여기서는 4, 5가 연결되어 있기 때문에 큐는 원래 있던 3과 4, 5가 추가된다.
노드 3 방문
Queue : [4, 5]
큐의 제일 앞에 있는 3을 꺼내어 방문한다.
3에는 더이상 연결되어 있는 노드가 없기 때문에 아무것도 추가하지 않는다.
노드 4 방문
Queue : [5]
큐의 제일 앞에 있는 4를 꺼내어 방문한다.
4도 더이상 연결되어 있는 노드가 없기 때문에 추가하지 않는다.
노드 5 방문
Queue : []
큐의 제일 앞에 있는 5를 꺼내어 방문한다.
더이상 추가할 노드가 없고, 큐도 비었기 때문에 BFS를 종료하게 된다.
BFS 알고리즘 ( 너비 우선 탐색)은 주변 노드들을 먼저 탐색하기 때문에
0 -> 1 -> 2 -> 3 -> 4 -> 5의 순서대로 탐색하게 된다.
BFS는 활용도가 무궁무진하다고 생각한다.
그리고 그 중에 많이 쓰이는 것들을 몇개 추려 보았다
대부분의 문제 유형이 비슷한 느낌인데
그래프 문제에서 주로 최단경로, 적절한 길을 찾는 문제에 많이 사용한다고 생각하면 될 것 같다.
최단 경로에서 BFS가 유용한 이유는 BFS 알고리즘이 현재 노드의 인접 노드들을 하나씩 모두 확인하기 때문에 가장 먼저 찾아지는 경로가 곧 최단거리이기 때문이다!!
최단경로를 찾을 수는 있지만 그래프의 크기가 매우 클 경우 메모리 소모가 크고 최악의 비효율적일 수 있다. 따라서 그래프의 크기가 크다면 dfs를 사용하는 것이 더 맞다.
노드 수 (V), 간선 수 (E) 일때
O(V+E)의 시간복잡도를 가진다.
BFS 알고리즘을 #include <queue> 헤더를 사용해서 구현하면 간단하게 할 수 있다.
DFS와 마찬가지로 visited 배열이 있어야 하고
각 노드에 방문할 때마다 visited 배열을 true로 만들고 연결된 노드들을 큐에 넣어 준다.
그리고 큐가 빌때까지(모두 방문할때까지) while문을 돌리며 반복한다.
void BFS(int V, vector<int> adj[], int s) { vector<bool> visited(V, false); queue<int> queue; visited[s] = true; queue.push(s); while(!queue.empty()) { s = queue.front(); cout << s << " "; queue.pop(); for (int i = 0; i < adj[s].size(); i++) { if (!visited[adj[s][i]]) { visited[adj[s][i]] = true; queue.push(adj[s][i]); } } } }
전체적인 방법은 DFS와 비슷한 것 같다.
단지 queue냐 stack이냐의 차이로 구현하면 될 것 같다.
비전공자도 배울 수 있는 타입스크립트 자바스크립트는 이상하게 정이안가는 언어중에 하나이다. 분명 web을 처음 시작했을 때…
IT 엔지니어를 위한 AWS 운영의 기본과 노하우 선택한 이유 AWS는 정말 공부해야지 공부해야지... 하면서도 쉽게…
개발하는 남자의 핸즈온 플러터 최근 계속해서 플러터를 개발할 일들이 많은데, 워낙 가지고 있는 강의들은 많은데…
갑자기 독스헌트 사업계획서? 아직 거창한 사업계획서를 쓸일은 없지만, 최근 진행하는 프로젝트의 지원금을 받을 수 있을까…