그래프 순회(traversal)은 모든 정점(Node)를 방문하는 작업을 말합니다.
대표적으로 깊이 우선 탐색(DFS: Depth First Search)와 너비 우선 탐색(BFS: Breath First Search)방식이 있는데요. 둘 다 그래프에서 최단 경로를 찾는 노드 기반 알고리즘 입니다.
말 그대로 깊은 곳부터 탐색을 진행하는 방식입니다.
트리의 전위순회와 유사한 방식을 따릅니다.
재귀 알고리즘이나 인접 리스트와 스택을 활용하여 쉽게 구현할 수 있습니다.
public static void dfs(int start) {
visited[start] = true;
// 필요하다면 오름차순 정렬
// graph[start].sort(Comparator.naturalOrder());
for (int node : graph[start]) {
if(!visited[node]) { // 인접 노드를 방문한 적 없다면 DFS 진행
dfs(node);
}
}
}
public static void dfs(int start) {
Stack<Integer> stack = new Stack<>();
stack.push(start);
visited[start] = true;
while (!stack.isEmpty()) { // 스택이 빌 때까지 반복
int node = stack.pop();
for (int neighbor : graph[node]) {
if(!visited[neighbor]) { // 인접 노드를 방문한 적 없다면 Stack에 push
stack.push(neighbor);
visited[neighbor] = true;
}
}
}
}
이때 시간 복잡도는 V가 노드의 수, E가 간선의 수 일 때 O(V + E) 입니다.
말 그대로 같은 레벨에 있는 노드를 따라 옆으로 탐색을 진행하는 방식입니다.
레벨은 시작 정점에서의 거리를 의미합니다.
이는 큐(Queue) 자료구조를 활용하여 쉽게 구현할 수 있습니다.
public static void bfs(int start) {
Queue<Integer> q = new LinkedList<>();
visited[start] = true;
q.add(start);
while (!q.isEmpty()) {
int node = q.poll();
for (int neighbor : graph[node]) {
if (!visited[neighbor]) {
visited[neighbor] = true;
q.add(neighbor);
}
}
}
}
이때 시간 복잡도는 V가 노드의 수, E가 간선의 수 일 때 O(V + E) 입니다.