Problem Solving
DFS와 BFS
주씨.
2023. 12. 24. 17:04
728x90
# DFS
- 스택 자료구조 사용
* 구체적인 동작 과정
- 탐색 시작 노드를 스택에 삽입하고 방문 처리
- 스택의 최상단 노드에
if 방문하지 않은 인접 노드가 있다 :
그 인접 노드를 스택에 넣고 방문처리. (재귀함수 호출)
elif 방문하지 않은 인접 노드가 없다 :
스택에서 저 최상단 노드 꺼내 - 2번의 과정을 더 수행할 수 없을 때까지 반복
- 실제로는 스택을 쓰지 않아도 되고, 탐색을 수행함에 있어서 데이터 개수가 N개인 경우 O(N)의 시간이 소요된다.
- DFS는 스택을 사용하는 알고리즘이라 실제 구현은 재귀 함수를 이용했을 때 매우 간결하게 구현할 수 있다.
# BFS
- 큐 자료구조 사용
* 구체적인 동작 과정
- 탐색 시작 노드를 큐에 삽입하고 방문 처리를 한다
- 큐에서 노드를 꺼내 해당 노드의 인접 노드 중에서 방문하지 않은 노드를 모두 큐에 삽입하고 방문 처리를 한다.
- 2번의 과정을 더 이상 수행할 수 없을 때까지 반복
- deque 라이브러리를 사용하는 것이 좋으며, O(N) 시간 소요
- 수행시간은 일반적으로 DFS 보다 좋다.
* 코딩 테스트 중 2차원 배열에서의 탐색 문제를 만나면 그래프 형태로 바꿔 DFS, BFS 를 수행하면, 풀이를 더 쉽게 할 수 있다.
# DFS, BFS 예시 코드
def dfs(graph, v, visited):
visited[v] = True # 현재 노드를 방문 처리
print(v, end= ' ')
for i in graph[v]: # 현재 노드와 연결된 다른 노드를 재귀적으로 방문
if not visited[i]:
dfs(graph, i, visited)
from collections import deque
def bfs(graph, start, visited):
queue = deque([start]) # 큐 구현을 위해 deque 라이브러리 사용
visited[start] = True # 현재 노드를 방문 처리
while queue: # 큐가 빌 때 까지 반복
v = queue.popleft() # 큐에서 원소를 하나 뽑아 출력
print(v, end=' ')
for i in graph[v]:
if not visited[i]:
queue.append(i)
visited[i] = True
graph = [
[],
[2, 3, 8], # 1번 노드는 2, 3, 8번 노드와 연결되어 있다
[1, 7], # 2번 노드는 1, 7번 노드와 연결되어 있다.
[1, 4, 5], # 이하동문
[3, 5],
[3, 4],
[7],
[2, 6, 8],
[1, 7]
]
# 각 노드가 방문된 정보를 리스트 자료형으로 표현
visited = [False] * 9
dfs(graph, 1, visited)
# Result : 1 2 7 6 8 3 4 5