topic★★★★★난이도 · 약 20분
그래프 · 인접리스트 · BFS/DFS 맛보기
SNS 친구·지도 길·웹 링크도 그래프. BFS(너비)는 최단 경로, DFS(깊이)는 탐색.
#그래프#BFS#DFS#인접리스트#최단경로
왜 배우는가
친구 추천·의존성 그래프·라우팅·추천 시스템·지식 트리 자체 — 현실 데이터의 절반이 그래프. Claude에게 'BFS로 최단 경로 찾아줘' 같은 지시가 가능해진다.
그래프 = 노드(vertex) + 간선(edge). 방향 유무(directed/undirected), 가중치 유무(weighted)로 나뉜다. 트리는 사이클 없는 연결 그래프의 특수 케이스.
| 표현 방식 | 방법 | 공간 | 장점 |
|---|---|---|---|
| 인접 리스트 | `{A: [B,C], B: [C]}` | O(V+E) | 희소 그래프에 효율적 (실무 기본) |
| 인접 행렬 | `matrix[A][B] = 1` | O(V²) | "연결돼?" O(1) 확인 |
| 간선 리스트 | `A,B], [B,C` | O(E) | 간단, Union-Find에 적합 |
javascript
// 인접 리스트로 그래프 표현 (가장 흔함)
const graph = {
A: ["B", "C"],
B: ["D"],
C: ["D", "E"],
D: [],
E: ["D"],
};
// ━━━ BFS (너비 우선) — 최단 경로, 레벨 순 ━━━
function bfs(start) {
const visited = new Set([start]);
const queue = [start];
while (queue.length) {
const node = queue.shift();
console.log(node);
for (const next of graph[node] || []) {
if (!visited.has(next)) {
visited.add(next);
queue.push(next);
}
}
}
}
bfs("A"); // A, B, C, D, E
// ━━━ DFS (깊이 우선) — 재귀 또는 스택 ━━━
function dfs(node, visited = new Set()) {
if (visited.has(node)) return;
visited.add(node);
console.log(node);
for (const next of graph[node] || []) dfs(next, visited);
}
dfs("A"); // A, B, D, C, EBFS = 큐, DFS = 재귀/스택. `visited` Set(ch17-2)이 무한 루프를 막는다. 바이브코딩에선 대부분 "친구의 친구", "의존성 순서"에 BFS가 답.
| 문제 | 적합한 방식 |
|---|---|
| "최단 거리(간선 수)" | BFS (가중치 없을 때) |
| "모든 경로 탐색", "백트래킹" | DFS |
| "사이클 감지" | DFS + visited 색칠 |
| "위상 정렬"(의존성 순서) | DFS 후 역순 또는 Kahn |
| "가중치 최단 경로" | Dijkstra (힙 + BFS 변형) |
| "최소 연결"(MST) | Kruskal / Prim |
실무 예시. npm 의존성 트리 = 그래프 + DFS로 순환 의존 감지. Google Maps = 가중 그래프 + Dijkstra. Instagram 친구 추천 = 2-hop BFS. 파일 링크 탐색 = DFS.
Union-Find(Disjoint Set)은 그래프 관련 고급 자료구조. "같은 그룹인가?" O(α(n)) (거의 O(1))으로 답한다. 친구 그룹 판별, MST 구축, 네트워크 연결성에 표준.
실기 드릴 2문항
edit실기 드릴 · 단답형
가중치 없는 그래프에서 최단 경로(간선 수 최소)를 찾는 탐색 방식은?
edit실기 드릴 · 단답형
그래프 탐색 시 무한 루프를 막기 위해 필요한 자료구조는?