DFS, BFS를 설명하기 전에, 그래프 표현의 2가지 방식은 인접 행렬과 인접 리스트에 대해 알아봅니다!
인접 행렬 (Adjacency Matrix)
- 2차원 배열에 각 노드가 연결된 형태를 기록
- 연결되지 않은 노드의 비용은 무한으로 작성한다
INF = int(1e9)
graph = [
[0, 1, 1, 1],
[0, 0, 1, 0],
[0, 0, 0, 0],
[0, 0, 1, 0]
]
인접 리스트 (Adjacency List)
- 모든 노드에 대해 연결된 노드에 대한 정보를 연결하여 저장
adj = [[] for _ in range(4)]
adj[1].append(2)
adj[1].append(3)
adj[1].append(4)
adj[3].append(3)
adj[4].append(3)
- 가중치가 있는 경우
adj = [[] for _ in range(4)]
adj[1].append((2, 7))
adj[2].append((3, 2))
adj[3].append((2, 4))
adj[3].append((1, 3))
DFS (Depth-First Search; 깊이 우선 탐색)
- 스택을 이용한 DFS의 동작과정
1. 탐색 시작 노드를 스택에 넣고 방문 처리한다
2. 스택의 최상단 노드에 방문하지 않은 노드가 있으면, 그 인접 노드를 스택에 넣고 방문 처리한다. 인접 노드가 없으면 스택에서 최상단 노드를 꺼낸다
3. 2번 과정을 수행할 수 없을 때까지 반복한다
- 인접한 노드 중 방문하지 않은 노드가 여러 개일 때, 관행적으로 번호가 낮은 순서부터 처리하도록 구현한다
- 이동할 때마다 가중치가 붙어서 이동한다거나 이동 과정에서 여러 제약이 있을 경우 DFS로 구현하는 것이 좋다
- 시간 복잡도 : O(N)
- 실제 구현은 스택을 사용하기 보다는 재귀 함수를 이용하는 것이 간결하다
- 예제 코드 with Python
def dfs(graph, v, visited):
# 현재 노드 방문
visited[v] = True
print(v, end=' ')
# 현재 노드와 연결된 다른 노드 방문
for i in graph[v]:
if not visited[i]:
dfs(graph, i, visited)
graph = [
[],
[2, 3, 8],
[1, 7],
[1, 4, 5],
[3, 5],
[3, 4],
[7],
[2, 6, 8],
[1, 7]
]
visited = [False] * 9
dfs(graph, 1, visited)
# 1 2 7 6 8 3 4 5
BFS (Breadth First Search; 너비 우선 탐색)
- 큐를 이용한 BFS의 동작과정
1. 탐색 시작 노드를 큐에 넣고 방문처리한다
2. 큐에서 노드를 꺼내 노드의 인접 노드 중 방문하지 않은 노드를 모두 큐에 삽입하고 방문처리한다
3. 2번 과정을 수행할 수 없을 때까지 반복한다
- 최단 거리 문제를 풀 때 사용하면 좋다
- 시간 복잡도 : O(N) 💨 일반적으로 실제 수행 시간이 DFS보다 좋은 편이다
- deque 라이브러리 이용
- 예제 코드 with Python
from collections import deque
def bfs(graph, start, visited):
queue = deque([start])
# 현재 노드 방문 처리
visited[start] = True
# 큐가 반복될 때까지
while queue:
# 큐에서 원소 꺼내서 출력
v = queue.popleft()
print(v, end=' ')
# 해당 원소와 연결된, 방문하지 않은 원소 큐에 넣기
for i in graph[v]:
if not visited[v]:
queue.append(i)
visited[i] = True
graph = [
[],
[2, 3, 8],
[1, 7],
[1, 4, 5],
[3, 5],
[3, 4],
[7],
[2, 6, 8],
[1, 7]
]
visited = [False] * 9
bfs(graph, 1, visited)
# 1 2 3 8 7 4 5 6
📚 참고서적 : 이것이 코딩테스트다 with 파이썬
'Computer Science > Algorithm' 카테고리의 다른 글
[Algorithm] 이진 탐색 (Binary Search) : 과정 및 예제 코드 (0) | 2021.09.04 |
---|---|
[Algorithm] 정렬 (Sorting) : 선택 정렬, 삽입 정렬, 퀵 정렬, 계수 정렬 파이썬 정렬 라이브러리 예제 코드 및 시간 복잡도 (0) | 2021.09.04 |
[Algorithm] 파이썬에서 스택(Stack)과 큐(Queue)의 사용 (0) | 2021.09.01 |
[Algorithm] 리스트 컴프리헨션 (List Comprehension) (0) | 2021.09.01 |
[Algorithm] 구현 문제 (Implementation) with 방향 이동(dx, dy) (0) | 2021.09.01 |