BFS는 너비 우선 검색이고, 가까운 레벨/가까운 노드를 먼저 검색하는 방식으로 수행되는 알고리즘이다. 최종 목표는 모든 노드(정점)을 탐색하는 것이다.
큐(Queue)를 사용하고, DFS 대비 최단 거리/비용을 계산하는데 효율적인 알고리즘이다.
그림으로 BFS를 이해하기
아래의 그래프를 통해서 BFS의 매커니즘을 이해해본다.
크게 8개의 정점, 9개의 간선, 오른쪽에는 큐(Queue)가 있다.
1. 1번 노드를 먼저 검색한다. 1번 노드를 큐에 담고, 내가 해당 노드를 탐색했다는 것을 의미하는 "방문처리"를 해야 한다. 방문 처리는 그림 상에서 파란색으로 표기했다.
큐(Queue)는 FIFO(First In First Out) 특성을 지닌 자료구조로, 먼저 들어간 것이 먼저 밖으로 나온다.
2. 큐에서 한개를 꺼내고, 연결된 노드들을 큐에 모두 넣는다.
즉, 큐에 있는 1번 노드를 꺼내서 출력하고, 1번과 연결된 2,3 노드를 큐에 담는다. 마지막으로 큐에 넣은 노드를 내가 검색하고 탐색한 노드이니까, 방문 처리(파란노드로 변경) 한다.
3. 큐에서 한개를 꺼내고 연결된 노드들을 큐에 모두 넣는다.
2번 노드를 꺼내고, 2번 노드와 연결된 노드인 6,8 노드를 큐에 담는다. 그리고 6,8은 내가 확인한 노드이니, 역시나 방문처리를 한다.
4. 마찬가지로 큐에서 3번 노드를 꺼내고, 연결된 노드인 5번 노드를 큐에 넣는다. 꺼낸 노드는 출력한다.
5. 큐에서 6번 노드를 꺼내고, 6번 노드와 연결된 노드가 없으므로 다시 큐에서 하나의 노드를 꺼낸다.
다음으로 꺼낼 노드는 8번이고, 8번 노드와 연결된 노드는 이미 방문처리된 것들 뿐이므로, 다시 큐에서 노드를 꺼낸다.
6. 큐에서 5번 노드를 꺼내고, 5번 노드와 연결된 4,7번 노드를 큐에 담는다. 큐에 담은 4,7번 노드는 방문 처리하고, 꺼낸 5번 노드는 출력한다.
7. 큐에서 노드 하나를 꺼내고, 방문하지 않은 노드를 찾아서 큐에 담는다.
즉, 4번 노드를 꺼내지면, 4번 노드와 연결된 노드 중에서 방문하지 않은 노드는 없으므로, 출력만 한다.
다시 7번 노드를 꺼내고 방문하지 않는 노드를 찾지만 없으므로, 출력하고 끝낸다.
최종적으로 1, 2, 3, 6, 8, 5, 4, 7 순으로 방문한다는 결론에 이른다.
(여기서는 오름차순 기준으로 큐에 넣는다는 가정으로 설명하였으며, 실제 내부적인 기준에 따라서 결과는 일부 달라질 수 있다.)
JAVA로 구현한 BFS 사례
import java.util.LinkedList;
import java.util.Queue;
public class bfs_queue {
// 방문처리를 위한 boolean 배열 선언
static boolean[] visited = new boolean[9];
static int[][] graph = {{}, {2,3,8}, {1,6,8}, {1,5}, {5,7}, {3,4,7}, {2}, {4,5}, {1,2}};
public static void main(String[] args) {
bfs(1);
}
static void bfs(int start) {
Queue<Integer> q = new LinkedList<Integer>();
// 큐에 BFS를 시작할 노드번호 담기
q.offer(start);
// 큐에 넣은 노드를 방문처리
visited[start] = true;
// 큐가 비어있을 때까지 반복수행
while(!q.isEmpty()) {
int node_out = q.poll(); // 큐에서 1개 노드 꺼내기
System.out.print(node_out + "->"); // 꺼낸 노드 출력
for(int i=0 ; i < graph[node_out].length ; i++) {
int temp = graph[node_out][i];
// 방문하지 않은 경우만 if 문 수행
if(!visited[temp]) { // 방문하지 않은 노드라면
visited[temp] = true; // 방문 처리한 후에
q.offer(temp); // 큐에 넣는다.
}
}
}
}
}
출력된 결과는 다음과 같다.
1->2->3->8->6->5->4->7->
'공부 기록' 카테고리의 다른 글
(다익스트라) 백준 1753 - 최단경로 (1) | 2023.09.04 |
---|---|
[알고리즘/JAVA] DFS(깊이 우선 검색, Depth First Search) (0) | 2023.08.20 |
[Java] For문 2가지 유형 (1) | 2023.08.19 |
[Java] Arrays.sort 통한 배열 정렬 (1) | 2023.08.06 |
[알고리즘/JAVA/Union-find] 유니온 파인드 (0) | 2023.08.04 |