math
CHAPTER 22 / 45
읽기 약 2분
FUNCTION
BFS와 DFS: 그래프 탐색
핵심 개념
너비 우선 탐색(BFS, 큐) vs 깊이 우선 탐색(DFS, 스택/재귀). 최단 경로·웹 크롤러·파일 시스템.
본문
두 탐색 비교
| 측면 | BFS | DFS |
|---|---|---|
| 자료구조 | 큐 (FIFO) | 스택 또는 재귀 |
| 탐색 순서 | 같은 거리 먼저 | 한 길 끝까지 |
| 최단 경로 | ✅ 보장 (무가중치) | ❌ 보장 안 됨 |
| 메모리 | O(V) (너비) | O(h) (깊이) |
| 실전 | 최단 경로, 레벨 | 백트래킹, 사이클 |
BFS — 큐 사용
from collections import deque
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E'],
}
def bfs(graph, start):
visited = {start}
queue = deque([start])
order = []
while queue:
node = queue.popleft()
order.append(node)
for neighbor in graph[node]:
if neighbor not in visited:
visited.add(neighbor)
queue.append(neighbor)
return order
print(bfs(graph, 'A')) # ['A', 'B', 'C', 'D', 'E', 'F']
# BFS는 시작점에서 거리별로 탐색
# A (거리 0) → B, C (거리 1) → D, E, F (거리 2)DFS — 재귀 또는 스택
# DFS 재귀
def dfs_recursive(graph, node, visited=None, order=None):
if visited is None:
visited = set()
order = []
visited.add(node)
order.append(node)
for neighbor in graph[node]:
if neighbor not in visited:
dfs_recursive(graph, neighbor, visited, order)
return order
print(dfs_recursive(graph, 'A')) # ['A', 'B', 'D', 'E', 'F', 'C']
# DFS 스택 (재귀 없이)
def dfs_iterative(graph, start):
visited = {start}
stack = [start]
order = []
while stack:
node = stack.pop()
order.append(node)
for neighbor in graph[node]: # 역순 추가하면 재귀와 같은 결과
if neighbor not in visited:
visited.add(neighbor)
stack.append(neighbor)
return order
print(dfs_iterative(graph, 'A'))최단 경로 — BFS
# 무가중치 그래프에서 최단 경로 — BFS
def shortest_path(graph, start, end):
if start == end:
return [start]
visited = {start}
queue = deque([(start, [start])])
while queue:
node, path = queue.popleft()
for neighbor in graph[node]:
if neighbor == end:
return path + [neighbor]
if neighbor not in visited:
visited.add(neighbor)
queue.append((neighbor, path + [neighbor]))
return None # 경로 없음
print(shortest_path(graph, 'A', 'F')) # ['A', 'C', 'F']
print(shortest_path(graph, 'D', 'F')) # ['D', 'B', 'E', 'F']
# 가중치 있으면 → Dijkstra (모듈 5에서)실전 — 웹 크롤러 (BFS)
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
# ⚠️ robots.txt 준수 + 본인 사이트만
def crawl_bfs(start_url, max_pages=10):
visited = {start_url}
queue = deque([start_url])
pages = []
while queue and len(pages) < max_pages:
url = queue.popleft()
try:
r = requests.get(url, timeout=5)
pages.append((url, len(r.text)))
soup = BeautifulSoup(r.text, 'html.parser')
for link in soup.find_all('a', href=True):
full_url = urljoin(url, link['href'])
if full_url not in visited and full_url.startswith(start_url):
visited.add(full_url)
queue.append(full_url)
except Exception:
continue
return pages
# pages = crawl_bfs('https://my-site.local', max_pages=20)실전 — 파일 시스템 탐색 (DFS)
import os
def find_files_dfs(root, pattern):
"""DFS로 파일 찾기 — 재귀"""
matches = []
for entry in os.listdir(root):
path = os.path.join(root, entry)
if os.path.isdir(path):
matches.extend(find_files_dfs(path, pattern))
elif pattern in entry:
matches.append(path)
return matches
# matches = find_files_dfs('src', '.tsx')
# print(f"찾은 파일: {len(matches)}개")실전 — React 컴포넌트 트리 순회
# 컴포넌트 트리 (CH.21에서 정의)
component_tree = {
'App': ['Header', 'Main', 'Footer'],
'Header': ['Logo', 'Nav'],
'Nav': ['NavItem1', 'NavItem2'],
'Main': ['Article'],
'Article': ['Title', 'Content'],
'Logo': [], 'NavItem1': [], 'NavItem2': [],
'Title': [], 'Content': [], 'Footer': [],
}
# 모든 컴포넌트 + 깊이
def render_tree(graph, node, depth=0):
print(' ' * depth + node)
for child in graph.get(node, []):
render_tree(graph, child, depth + 1)
render_tree(component_tree, 'App')
# DFS — 한 가지 끝까지 갔다가 돌아옴BFS vs DFS 선택 가이드
BFS 사용:
- 최단 경로 (무가중치)
- 레벨별 처리 (트리의 같은 깊이)
- 가까운 것부터 (지인의 지인)
DFS 사용:
- 백트래킹 (8 Queens, 스도쿠)
- 사이클 탐지
- 위상 정렬
- 메모리 제약 (스택 깊이만)다음 챕터
CH.23 "트리" — 그래프의 특수 형태 + 이진 탐색 트리.
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 그래프 데이터에서 시작점과 끝점을 주면 BFS 최단 경로 + DFS 모든 경로를 시각화해서 보여줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
한국 게임 길찾기 알고리즘 사례 (BFS vs A*)와 실제 성능 차이를 알려줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 코드의 의존성 그래프 전체에서 DFS로 순환 참조 + 위상 정렬 결과를 보고해줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 분산 그래프 처리(GraphX/Pregel) 실무 활용과 BFS/DFS 한계를 솔직히 알려줘.
⭐ 이것만 기억하세요
BFS와 DFS: 그래프 탐색은 이 3가지만 확실히 잡으세요
1.BFS는 큐(가까운 것 먼저), DFS는 스택/재귀(끝까지 갔다 돌아오기) — 핵심 차이
2.최단 경로는 무가중치면 BFS, 가중치 있으면 Dijkstra (모듈 5)
3.다음 챕터 CH.23에서 트리 — 그래프의 특수 형태와 이진 탐색 트리
공유하기
진행도 22 / 45