(자세한 개념 설명보다는 구현 위주의 글입니다.)
DFS,BFS 개념 습득은 아래의 영상을 참고하시길 추천드립니다.
https://www.youtube.com/watch?v=_hxFgg7TLZQ
[재귀]
재귀로는 일단 지점 1부터 지점1이 연결되는 끝까지 파고 들어간 다음,
다시 하나 올라와서 올라온 지점의 다른 경로로부터 탐색을 다시 시작한다.
[스택]
스택은 시작 지점을 먼저 삽입하고, 시작지점과 연결된 지점들을 모두 스택에 넣는다.
그 후 가장 마지막에 삽입된 지점부터 꺼내서(pop),
그 지점의 하위 지점을 탐색하고 스택에 넣는다.
그리고 마지막에 삽입 된 지점을 꺼내기 때문에, 2번에 삽입한 지점이 끝까지 탐색하기 전까지는 1번에서 넣었던 나머지 지점을 탐색할 수 없다.
즉, 가장 마지막에 넣은 지점부터 계속 탐색 한다고 보면 된다.
**여기서 백트래킹을 잠깐 알고가자.
**
백트래킹을 잘 설명한 글
# 인접간선 설명
graph = {
1: [2,3,4],
2:[5],
3:[5],
4:[],
5:[6,7],
6:[],
7:[3],
}
# 재귀로 구현한 코드
def recursive_dfs(vertex, visited=[]):
visited.append(vertex)
for item in graph[vertex]:
if not item in visited:
visited = recursive__dfs(item, visited)
return visited
# 스택으로 구현한 코드
def stack_dfs(start_vertex):
visited = []
stack = [start_vertex]
while stack:
vertex = stack.pop()
if vertex not in visited:
visited.append(vertex)
for item in graph[vertex]:
stack.append(item)
return visited
지점들(vertex)을 순서대로 큐에 넣고 하나 뽑고(pop)
그 뽑은 지점의 하위 경로를 다시 큐에 넣고
그 다음 지점을 큐에서 뽑고
그 지점의 하위 경로를 다시 큐에 넣고.. 하는 식으로 진행된다.
이렇게 구현하면 먼저 넣은 지점들부터 탐색하고 그 후 그 지점들의 하위 지점들을 탐색하는 식으로 진행 된다.
여기서는 리스트를 썼지만 좀 더 효율적으로 사용하려면 deque 같은 자료형을 써도 좋을 것 같다.
# graph는 위의 리스트 사용
def iterative_bfs(start_vertex):
visited = [start_vertex]
queue = [start_vertex]
while queue:
vertex = queue.pop(0)
for item in graph[vertex]:
if item no in visited:
visited.append(item)
queue.append(item)
return visited
참고로 BFS는 재귀로 동작하지 않는다.
BFS 참고 : https://gmlwjd9405.github.io/2018/08/15/algorithm-bfs.html