CS/알고리즘
[BFS/DFS] 너비우선탐색과 깊이우선탐색
지잉지잉
2021. 8. 31. 23:08
BFS(Breadth First Search, 너비 우선 탐색)
- 정점들과 같은 레벨에 있는 노드를 먼저 탐색함.
- 구현에 큐를 사용한다.
- Root Node로부터 가장 가까운 Node부터 탐색하므로 Root Node와 가까이 있는 Target Node를 찾는데 유용하다.
- 최단거리 탐색, SNS 친구추천 등에 사용되고 있음.
- 시간복잡도 O(N)
DFS(Depth First Search, 깊이 우선 탐색)
- Root Node에 이어진 Child Node들 부터 먼저 탐색함.
- 구현에 스택을 사용한다.
- BFS보다 속도가 느릴 수 있다.
- 미로게임 등에서 경로가 존재하는지 여부를 판단할 때 유용하다.
- 시간복잡도 O(N)
탐색 방식 비교
- BFS: A - B - C - D - G - H - I - E - F - J
- DFS: A - B - D - E - F - C - G - H - I - J
BFS 구현
const graph = {
A: ["B", "C"],
B: ["A", "D"],
C: ["A", "G", "H", "I"],
D: ["B", "E", "F"],
E: ["D"],
F: ["D"],
G: ["C"],
H: ["C"],
I: ["C", "J"],
J: ["I"]
};
const bfs = (graph, startNode) => {
let visited = []; // 탐색 완료 노드
let notVisit = []; // 아직 탐색하지 않은 노드
notVisit.push(startNode);
while (notVisit.length !== 0) { // 탐색을 모두 완료할 때 까지 반복
const node = notVisit.shift(); // 맨 앞에 있는 노드
if (!visited.includes(node)) { // 해당 노드가 탐색된 적 없다면
visited.push(node);
notVisit = [...notVisit, ...graph[node]];
}
}
return visited;
};
console.log(bfs(graph, "A"));
// ["A", "B", "C", "D", "G", "H", "I", "E", "F", "J"]
DFS 구현
const graph = {
A: ["B", "C"],
B: ["A", "D"],
C: ["A", "G", "H", "I"],
D: ["B", "E", "F"],
E: ["D"],
F: ["D"],
G: ["C"],
H: ["C"],
I: ["C", "J"],
J: ["I"],
};
// (graph, 시작 정점)
const dfs = (graph, startNode) => {
let notVisitStack = []; // 탐색하지 않은 노드
let visitedQueue = []; // 탐색종료 노드
needVisitStack.push(startNode);
while (notVisitStack.length !== 0) { // 모든 노드가 탐색 완료시 까지
const node = notVisitStack.pop();
if (!visitedQueue.includes(node)) {
visitedQueue.push(node);
notVisitStack = [...notVisitStack, ...graph[node]];
}
}
return visitedQueue;
};
console.log(dfs(graph, "A"));
// ["A", "C", "I", "J", "H", "G", "B", "D", "F", "E"]
참고자료: https://youtube.com/watch?v=_hxFgg7TLZQ&feature=share