그래프 상에 존재하는 임의의 한 정점으로부터 연결되어 있는 한 정점으로만 나아간다라는 방법을 우선으로 탐색한다.
-> 한 갈래로 갈 수 있는 만큼 최대한 깊게 파고들면서 탐색한다.
연결할 수 있는 정점이 있을 때까지 계속 연결하다가 더 이상 연결될 수 있는 정점이 없으면 바로 그 전 단계의 정점으로 돌아가서 연결할 수 있는 정점이 있는지 살펴봐야 할 것이다.
-> 미로를 탐색할 때 막 다른길에 마주하면 지나온 길을 되돌아간다.
어떤 자료구조를 사용해야할까? 바로 Stack 이다.
[A]
/ \
[B] [C]
/ \ |
[D] [E] |
\ |
\ |
\ |
\ |
\|
[F]
const graph = {
'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F'],
'D': [],
'E': ['F'],
'F': []
};
// 방문한 노드를 저장할 배열 선언
const visited = []
function dfs(node) {
visited.push(node); // 현재 노드를 방문한 것으로 표시
const neighbors = graph[node]; // 인접노드들
for (let i = 0; i < neighbors.length; i++) {
const neighbor = neighbors[i]; // 인접 노드
if (!visited.includes(neighbor)) { // 방문하지 않았다면
dfs(neighbor); // 방문하지 않은 인접한 노드에 대해 재귀적으로 DFS를 호출.
}
}
return visited
}
// 루트 노드 'A'부터 시작
dfs('A');
BFS는 한 정점에서 시작하여 연결된 정점들을 레벨 순서로 탐색하는 방법이다.
시작 정점을 큐에 넣고, 큐에서 정점을 꺼내면서 연결된 정점들을 큐에 추가하는 방식으로 진행
-> 깊게(deep) 탐색하기 전에 넓게(wide) 탐색
-> 주로 두 노드 사이의 최단 경로 혹은 임의의 경로를 찾고 싶을 때 사용하는 방법
BFS 장점
노드의 수가 적고 깊이가 얕은 경우 빠르게 동작할 수 있다.
단순 검색 속도가 DFS보다 빠르다.
최단 경로가 존재한다면 어느 한 경로가 무한히 깊어진다고 해도 최단 경로를 반드시 찾을 수 있다.
// 그래프의 인접 리스트를 사용하여 그래프를 표현합니다.
const graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
};
function bfs(startNode) {
const visited = []; // 방문한 노드를 저장할 Set 객체를 생성합니다.
const queue = []; // 큐를 초기화합니다.
queue.push(startNode); // 시작 노드를 큐에 넣습니다.
visited.push(startNode); // 시작 노드를 방문한 것으로 표시합니다.
while (queue.length > 0) {
const currentNode = queue.shift(); // 큐에서 노드를 꺼냅니다.
const neighbors = graph[currentNode]; // 현재 노드의 인접한 노드들을 가져옵니다.
for (let i = 0; i < neighbors.length; i++) {
const neighbor = neighbors[i];
if (!visited.includes(neighbor)) {
queue.push(neighbor); // 방문하지 않은 인접한 노드를 큐에 넣습니다.
visited.push(neighbor); // 방문한 노드로 표시합니다.
}
}
}
}
// 시작 노드 'A'에서 BFS를 실행합니다.
bfs('A');
BFS의 장점
BFS의 단점
훌륭한 글이네요. 감사합니다.