Depth First Search, DFS
오늘은 DFS를 알아보자
DFS는 트리나 그래프를 방문 또는 탐색할때 깊이를 우선으로 하는 알고리즘이다.
탐색 방법
1. 시작하는 칸을 스택에 넣고 방문했다는 표시를 남김
2. 스택에서 원소를 꺼내어 그 칸과 상하좌우로 인접한 칸에 대해 3번을 진행
3. 해당 칸을 이전에 방문했다면 아무 것도 하지 않고, 처음으로 방문했다면 방문했다는 표시를 남기고 해당 칸을 스택에 삽입
4.스택이 빌때까지 2번을 반복
시간복잡도는 O(N)
BFS과정에서 큐 대신 스택을 쓰면 DFS!
그림을 보면, DFS는 갈림길에서 하나의 길로 들어서서 막다른 길이 나올 때까지 깊게 탐색을 하는 것을 볼 수 있고, BFS는 갈림길에 연결되어 있는 모든 길을 한번씩 탐색한 뒤 다시 연결되어 있는 모든 길을 넓게 탐색하는 것을 볼 수 있다.
코드 구현
1. 시작하는 칸을 스택에 넣고 방문했다는 표시를 남김
2. 스택에서 원소를 꺼내어 그 칸과 상하좌우로 인접한 칸에 대해 3번을 진행
3. 해당 칸을 이전에 방문했다면 아무 것도 하지 않고, 처음으로 방문했다면 방문했다는 표시를 남기고 해당 칸을 스택에 삽입
4.스택이 빌때까지 2번을 반복
dfs(그래프 탐색) -재귀
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],
[1, 8],
[1, 4, 5],
[3, 5],
[3, 4],
[7, 8],
[6, 8],
[2, 6, 7]
]
# 노드별로 방문 정보를 리스트로 표현
visited = [False] * 9
dfs(graph, 1, visited)
dfs(그래프 탐색) - 스택
def dfs_stack(graph, start, visited):
# 스택 구현을 위한 리스트 사용
stack = [start]
# 현재 노드를 방문 처리
visited[start] = True
while stack:
# 스택에서 가장 최근에 삽입된 노드를 꺼내기
v = stack.pop()
# 탐색 순서 출력
print(v, end=' ')
# 현재 노드와 연결된 노드들을 스택에 삽입
# 이때 방문하지 않은 노드들만 삽입
for i in reversed(graph[v]):
if not visited[i]:
stack.append(i)
visited[i] = True
graph = [
[],
[2, 3],
[1, 8],
[1, 4, 5],
[3, 5],
[3, 4],
[7, 8],
[6, 8],
[2, 6, 7]
]
# 노드별로 방문 정보를 리스트로 표현
visited = [False] * 9
dfs_stack(graph, 1, visited)
dfs(2차원 배열)
def dfs_stack(graph, visited):
# 상하좌우 네 방향을 의미
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
# 스택 구현을 위한 리스트 사용
stack = [(0, 0)]
# 현재 노드를 방문 처리
visited[0][0] = True
while stack:
# 스택에서 가장 최근에 삽입된 노드를 꺼내기
x, y = stack.pop()
# 탐색 순서 출력
print(x, y, end=' ')
# 현재 노드와 연결된 노드들을 스택에 삽입
for i in range(4):
nx = x + dx[i]
ny = y + dy[i]
if 0 <= nx < len(graph) and 0 <= ny < len(graph[0]):
if not visited[nx][ny] and graph[nx][ny] == 'O':
visited[nx][ny] = True # 방문 표시
stack.append((nx, ny))
graph = [
['O', 'O', 'O', 'O', 'O', 'X'],
['O', 'O', 'O', 'O', 'X', 'O'],
['O', 'O', 'O', 'X', 'O', 'O'],
['O', 'O', 'X', 'O', 'O', 'O'],
['X', 'O', 'O', 'O', 'O', 'O'],
]
# 노드별 방문 정보
visited = [[False] * len(graph[0]) for _ in range(len(graph))]
dfs_stack(graph, visited)
'PS > DFS_BFS' 카테고리의 다른 글
[백준] 24481번, 24482번 : 알고리즘 수업 - 깊이 우선 탐색 3, 4 파이썬 (0) | 2024.06.22 |
---|---|
[백준] 24479번, 24480번 : 알고리즘 수업 - 깊이 우선 탐색 1, 2 파이썬 (0) | 2024.06.19 |
[백준] 14940번: 쉬운 최단거리 파이썬 (0) | 2024.04.03 |
[백준] 11724번: 연결 요소의 개수 파이썬 (0) | 2024.04.02 |
BFS(너비우선탐색) python으로 구현 (1) | 2024.04.01 |