깊이 우선 탐색
public class Main
{
public final static int GRAPH_LIST_SIZE = 9;
public static boolean[] visitedFlag = new boolean[GRAPH_LIST_SIZE];
public static ArrayList<ArrayList<Integer>> graph = new ArrayList<ArrayList<Integer>>();
public static void main(String[] args) {
// 리스트 초기화
for (int i = 0; i < GRAPH_LIST_SIZE; i++) {
graph.add(new ArrayList<Integer>());
}
// 노드 1에 연결된 노드 정보를 저장
graph.get(1).add(2);
graph.get(1).add(3);
graph.get(1).add(8);
// 노드 2에 연결된 노드 정보를 저장
graph.get(2).add(1);
graph.get(2).add(7);
// 노드 3에 연결된 노드 정보를 저장
graph.get(3).add(1);
graph.get(3).add(4);
graph.get(3).add(5);
// 노드 4에 연결된 노드 정보를 저장
graph.get(4).add(3);
graph.get(4).add(5);
// 노드 5에 연결된 노드 정보를 저장
graph.get(5).add(3);
graph.get(5).add(4);
// 노드 6에 연결된 노드 정보를 저장
graph.get(6).add(7);
// 노드 7에 연결된 노드 정보를 저장
graph.get(7).add(2);
graph.get(7).add(6);
graph.get(7).add(8);
// 노드 8에 연결된 노드 정보를 저장
graph.get(8).add(1);
dfs(1);
}
public static void dfs(int point) {
// 현재 노드 방문 처리하기
visitedFlag[point] = true;
System.out.print(point + " ");
// 인접 노드 방문
for(int node : graph.get(point)) {
if(!visitedFlag[node]) {
dfs(node);
}
}
}
}
너비 우선 탐색
import java.util.*;
public class Main
{
public final static int GRAPH_LIST_SIZE = 9;
public static boolean[] visitedFlag = new boolean[GRAPH_LIST_SIZE];
public static ArrayList<ArrayList<Integer>> graph = new ArrayList<ArrayList<Integer>>();
public static void main(String[] args) {
// 리스트 초기화
for (int i = 0; i < GRAPH_LIST_SIZE; i++) {
graph.add(new ArrayList<Integer>());
}
// 노드 1에 연결된 노드 정보 저장
graph.get(1).add(2);
graph.get(1).add(3);
graph.get(1).add(8);
// 노드 2에 연결된 노드 정보 저장
graph.get(2).add(1);
graph.get(2).add(7);
// 노드 3에 연결된 노드 정보 저장
graph.get(3).add(1);
graph.get(3).add(4);
graph.get(3).add(5);
// 노드 4에 연결된 노드 정보 저장
graph.get(4).add(3);
graph.get(4).add(5);
// 노드 5에 연결된 노드 정보 저장
graph.get(5).add(3);
graph.get(5).add(4);
// 노드 6에 연결된 노드 정보 저장
graph.get(6).add(7);
// 노드 7에 연결된 노드 정보 저장
graph.get(7).add(2);
graph.get(7).add(6);
graph.get(7).add(8);
// 노드 8에 연결된 노드 정보 저장
graph.get(8).add(1);
graph.get(8).add(7);
bfs(1);
}
// BFS 탐색을 위한 재귀함수
public static void bfs(int point){
Queue<Integer> queue = new LinkedList<Integer>();
// 현재 노드 방문 처리
queue.offer(point);
visitedFlag[point] = true;
while(!queue.isEmpty()){
int target = queue.poll();
System.out.print(target + " ");
// 인접 노드 방문
for(int node : graph.get(target)){
if(!visitedFlag[node]){
queue.offer(node);
visitedFlag[node] = true;
}
}
}
}
}
DFS와 다르게 재귀 함수 로직이 존재하지 않고
초기 점을 큐에 넣고 그 뒤부터는 큐가 empty 될 때까지 반복문을 돌려 큐에 남아있는 노드와 인접한 노드들을 다 방문하는 구조입니다.
백준의 촌수계산 문제가 DFS로 표현하기 좋은 문제라 예시로 가져왔습니다.
백준 촌수계산 (https://www.acmicpc.net/problem/2644)
import java.io.*;
import java.util.*;
public class Main {
static ArrayList<ArrayList<Integer>> graph = new ArrayList<ArrayList<Integer>>();
static boolean[] visitedFlag;
static int answer = -1;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
// 부모 - 자식 1촌
// 나 - 할아버지 2촌
// 나 - 아버지 형제 - 3촌
// 나를 기준으로 촌수 정하기
// 할아버지(2촌)
// 아버지(1촌) 아버지 형제(3촌)
// 나
// 입력 파일의 첫째 줄에는 전체 사람의 수 n이 주어지고,
// 둘째 줄에는 촌수를 계산해야 하는 서로 다른 두사람의 번호가 주어진다
// 셋째 줄에는 부모 자식들 간의 관계수 m이 주어진다.
// 넷째 줄부터는 부모 자식간의 관계를 나타내는 두 번호 x, y
// 이때 앞에 나오는 번호 x는 뒤에 나오는 정수 y의 부모 번호를 나타낸다.
int n = Integer.parseInt(br.readLine()); // 전체 사람의 수
StringTokenizer st = new StringTokenizer(br.readLine());
int person1 = Integer.parseInt(st.nextToken());
int person2 = Integer.parseInt(st.nextToken()); // 촌수를 계산해야 하는 서로 다른 두 사람의 번호
int m = Integer.parseInt(br.readLine()); // 부모 자식들 간의 관계 수 m
visitedFlag = new boolean[n+1];
// 리스트 초기화
for (int i = 0; i <= n; i++) {
graph.add(new ArrayList<Integer>());
}
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken()); // 부모
int y = Integer.parseInt(st.nextToken()); // 자식
graph.get(x).add(y);
graph.get(y).add(x);
}
dfs(person1,person2,0);
bw.write(answer+"");
bw.flush();
br.close();
bw.close();
}
static void dfs(int start, int end, int count) {
if (start == end) {
answer = count;
}
// 현재 노드 방문 처리
visitedFlag[start] = true;
for (int node : graph.get(start)) {
// 방문을 안 한
if (!visitedFlag[node]) {
dfs(node, end, count+1);
}
}
}
}
초기점(자식)과 끝점(부모)를 지정해주고 인접리스트에 자식노드와 부모노드를 넣어준 뒤에, 자식에서 부모까지 깊이 우선 탐색 방식으로 몇 회 이동하는지에 대한 로직으로 구성했습니다.