너비를 우선으로 탐색을 수행하는 알고리즘
맹목적인 탐색을 할 때 사용하는 기법
"최단 경로"를 찾아준다는 점에서 최단 길이를 보장해야 할 때 많이 사용함
ex) 지구 상에 존재하는 모든 친구 관계를 그래프로 표현한 후 Ash와 Vanessa 사이에 존재하는 경로를 찾는 경우
DFS - 모든 친구 관계를 다 살펴 봐야 함
BFS - Ash와 가까운 관계부터 탐색
필요한 자료구조는 Queue (FIFO : 선입선출의 원칙)
깊이가 1인 모든 노드 방문 후 깊이의 오름차순으로 방문하다가 더 이상 방문할 노드가 없다면 탐색을 종료한다
사용 언어 : c++
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int number = 7;
int check[5]; // 방문 처리를 위한 배열
vector<int> a[5]; // 각 노드의 인덱스가 1부터 처리될 수 있도록 만든 배열
void bfs(int start) {
queue<int> q;
q.push(start); // 시작 노드
check[start] = true; // 방문 처리
while (!q.empty()) { // queue가 비어있지 않다면(탐색 중)
int x = q.front(); // queue의 맨 처음 원소를 x에 넣고
q.pop(); // 빼낸다
cout << x << " ";
for (int i = 0; i < a[x].size(); i++) { // queue에서 꺼낸 인접한 노드를 방문하면서
int y = a[x][i]; // 방문을 하면서
if (!check[y]) { // 방문 한 상태가 아니라면
q.push(y); // queue에 노드를 넣어주고
check[y] = true; // 방문 처리를 해준다
}
}
}
}
int main() {
a[0].push_back(1);
a[1].push_back(0);
a[0].push_back(2);
a[2].push_back(0);
a[0].push_back(4);
a[4].push_back(0);
a[1].push_back(2);
a[2].push_back(1);
a[2].push_back(3);
a[3].push_back(2);
a[2].push_back(4);
a[4].push_back(2);
a[3].push_back(4);
a[4].push_back(3);
bfs(0);
return 0;
}
인접 리스트로 표현된 그래프 : O(N+E)
인접 행렬로 표현된 그래프 : O(N^2)
그래프 내에 적은 숫자의 간선만을 가지는 희소 그래프의 경우 인접 행렬보다 인접 리스트를 사용하는 것이 유리
인접 행렬 vs 인접 리스트
인접 행렬 : 2차원 배열
인접 리스트 : 링크드 리스트, 어레이 리스트, 어레이 리스트를 저장하는 어레이 리스트