15강 / 20강
BFS와 DFS — 관계망을 훑는 두 가지 방법
"이 상품과 2단계 안에 연결된 상품" 을 찾아라
14강에서 만든 '함께 구매' 그래프가 있습니다. 이제 진짜 문제를 풀어 봅시다.
"이어폰 상세 페이지에 추천 상품을 띄우려고 합니다. 직접 함께 산 상품뿐 아니라, 2단계까지 연결된 상품도 넣어 주세요. 단, 가까운 것부터 순서대로요."
이 요구를 그대로 구현하는 알고리즘이 BFS(너비 우선 탐색)입니다.
BFS의 핵심은 '큐'와 '방문 기록' 두 가지뿐입니다.
Python
브라우저에서 실행
같은 그래프를 DFS로 훑으면
DFS는 큐 대신 스택을 씁니다. 딱 그 한 글자 차이인데 훑는 순서가 완전히 달라져요.
popleft() 를 pop() 으로 바꾸면 BFS가 DFS가 됩니다.
Python
브라우저에서 실행
🎮 추천 확산 시뮬레이터
상품 하나를 클릭하면 관계망을 따라 추천이 퍼져 나갑니다. BFS는 동심원처럼, DFS는 뱀처럼 움직이는 걸 보세요. 단계 제한을 바꿔 가며 추천 개수가 어떻게 폭발하는지도 확인해 보세요.
BFS가 최단 거리를 보장하는 이유
BFS는 거리 1인 곳을 전부 본 다음에 거리 2로 넘어갑니다. 그래서 어떤 점에 처음 도달했을 때의 거리가 곧 최단 거리예요.
DFS는 이 보장이 없습니다. 운 나쁘면 먼 길로 먼저 도달할 수 있어요.
단, 이 보장은 간선의 비용이 모두 같을 때만 유효합니다. 배송비처럼 간선마다 비용이 다르면 다익스트라 알고리즘을 써야 하는데, 그건 BFS의 큐를 우선순위 큐로 바꾼 것입니다 — 11강에서 배운 그 힙이에요.
다익스트라 = BFS + 우선순위 큐. 8줄이면 됩니다.
Python
브라우저에서 실행
🤔 확인 문제
"이 상품과 2단계 이내로 연결된 상품을 가까운 순서로" — 적합한 알고리즘은?
해설 BFS는 거리가 가까운 것부터 한 겹씩 훑습니다. 단계 정보가 자연스럽게 따라오죠. DFS는 순서 보장이 없어요.
🤔 확인 문제
BFS 코드에서
큐.popleft() 를 스택.pop() 으로 바꾸면?해설 큐 → 스택이 BFS와 DFS의 유일한 차이입니다. 어느 쪽 끝에서 꺼내느냐가 전부예요.
🤔 확인 문제
배송비처럼 간선마다 비용이 다른 그래프에서 최소 비용 경로를 찾으려면?
해설 BFS의 최단 보장은 모든 간선 비용이 같을 때만 성립합니다. 비용이 다르면 다익스트라 — 큐를 힙으로 바꾼 BFS예요.