회고를 쓰는 건 한 주의 끝이라 그런 것일까?
다음 한 주를 시작하는 느낌으로 적어야 할 수 있다는 의지적인 힘이 생겨날 것 같은데 -
매주 지난주만큼이나 힘들었다고 이야기하게 되는 것 같다.
물론 힘들었는데 안 힘든 척 할 수는 없지만 말이다.
하루 하루를 곱씹어보면 가장 힘든 것이 무엇일까? 고민해보면,
말 그대로 '항해'. 바다 위를 지나는데 아직도 배멀미를 하는 것이 힘들다고 표현하는 게 적절하지 않나 싶다.
문제도 잘 풀리고, 이해도 잘 되고, 좋다! 싶을 때는 바람을 타고 잘- 나아가다가.
이해도 안 되고, 문제는 안 풀리고, 다른 사람들은 다 열심히 최선을 다해서 잘 하고 있는 것 같이 보일 때는 정말..
암초에 걸린 배처럼 답이 없다.
backtracking
이진트리
이진탐색트리
시험
힙
정렬
DFS(Depth-First Search)는 이름에서 알 수 있듯이 그래프 전체를 탐색하는 방법(i.e., 완전 탐색) 중 하나로서 그래프에서 특히 "깊이"를 우선적으로 탐색하는 알고리즘이다. 한 노드를 시작으로 다음 분기(branch)로 넘어가기 전에 해당 분기를 완벽하게 탐색한다는 특징이 있다.
DFS 알고리즘의 구체적인 동작 과정은 아래와 같다.
- 탐색 시작 노드 정보를 스택에 삽입하고 방문 처리 한다.
- 스택 내 최상단 노드에 방문하지 않은 노드가 있다면 그 인접 노드 정보를 스택에 삽입하고 방문 처리한다.
만일 방문하지 않은 인접 노드가 없다면 스택 내 최상단 노드를 꺼낸다.- 2번의 과정을 더 이상 수행할 수 없을 때까지 반복한다.
방문 처리란, 스택에 한 번이라도 삽입된 노드를 다시 삽입하지 않도록 체크하는 것을 의미한다.
즉, 방문 처리를 함으로써 각 노드를 한 번씩만 처리할 수 있게 한다.
DFS 구현 (python)
# DFS 메서드 정의
def dfs (graph, node, visited):
# 해당 노드를 방문 처리
visited[node] = True
# 탐색 순서 출력
print(node, end = ' ')
# 한 노드로부터 인접한 다른 노드를 재귀적으로 방문 처리
for i in graph[node]:
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 메서드 호출(노드 1을 탐색 시작 노드로 설정)
dfs(graph, 1, visited)
실행결과
1 2 6 8 6 7 3 4 5
BFS(Breadth-First Search)란 너비 우선 탐색이라고 불리며 그래프에서 가까운 노드부터 탐색하는 알고리즘이다.
BFS는 인접한 노드를 반복적으로 큐에 삽입하고 먼저 삽입된 노드부터 차례로 큐에서 꺼내도록 알고리즘을 작성하면 된다. BFS 알고리즘의 구체적인 동작 과정은 아래와 같다.
- 탐색 시작 노드 정보를 큐에 삽입하고 방문 처리 한다.
- 큐에서 노드를 꺼내 방문하지 않은 인접 노드 정보를 모두 큐에 삽입하고 방문 처리한다.
- 2번의 과정을 더 이상 수행할 수 없을 때까지 반복한다.
방문 처리란, 스택에 한 번이라도 삽입된 노드를 다시 삽입하지 않도록 체크하는 것을 의미한다.
즉, 방문 처리를 함으로써 각 노드를 한 번씩만 처리할 수 있게 한다.
BFS 알고리즘은 큐 자료구조에 기초하기 때문에 deque 라이브러리를 활용하여 구현하며 시간 복잡도는 O(N) 의 시간이 소요된다. 참고로 일반적인 경우에 실제 수행 시간은 DFS 보다 BFS가 좋은 편이다.
BFS 구현 (python)
# deque 라이브러리 불러오기
from collections import deque
# BFS 메서드 정의
def bfs (graph, node, visited):
# 큐 구현을 위한 deque 라이브러리 활용
queue = deque([node])
# 현재 노드를 방문 처리
visited[node] = 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],
[1, 8],
[1, 4, 5],
[3, 5],
[3, 4],
[7, 8],
[6, 8],
[2, 6, 7]
]
# 노드별로 방문 정보를 리스트로 표현
visited = [False] * 9
# 정의한 BFS 메서드 호출(노드 1을 탐색 시작 노드로 설정)
bfs(graph, 1, visited)
실행 결과
1 2 3 8 4 5 6 7
나는 나름 자기 객관화에 뛰어나다고 생각해왔다. 그런데, 알고리즘 공부와 CS 공부만큼은 어디서부터 어떻게 정리해가야 할지 감이 계속 잡히질 않는다. 나 자신을 완전히 바닥부터 놓고 시작하면.... 가능하지 않을까?
항해에는 설 연휴가 없지만, 어쨌든 챙겨야 할 가정이 있는 사람으로서 쉬는 시간들에 마음의 쉼을 가지면서.
나의 상태에서 내가 해야 할 것들에 대해 바닥부터 쌓아나가고 싶다.
알고리즘 !