Java

[Java] DFS, BFS

snoony 2025. 6. 2. 21:28

Java로 DFS, BFS 정리하기

이 글에서는 기본적인 DFS, BFS 알고리즘에 대한 설명을 포함하지 않습니다.

Java로 각 알고리즘을 구현하는 방식에 대해 작성하였습니다.

1. 그래프를 matrix로 표현하기

public class UndirectedGraph{
	private int count; // 노드 개수
	private int [][] vertexMatrix;
	
	public UndirectedGraph(int count) {
		this.count = count;
		vertexMatrix = new int[count][count];
	}
	
	public void addEdges(int from, int to, int weight) {
		vertexMatrix[from][to] = weight;
		vertexMatrix[to][from] = weight;
	}
	
	public int[][] getMatrix(){
		return vertexMatrix;
	}
}

2. 스택을 활용한 DFS 구현

Java에서 Stack 사용법

import java.util.Stack;

public class DfsSearch {
	int count;
	boolean[] visited;
	Stack<Integer> stack;
	int[][] matrix;
	
	public DfsSearch(int count) {
		this.count = count;
		visited = new boolean[count];
		stack = new Stack<Integer>();
	}
	
	public void dfsTraversal() {
		stack.push(0);
		visited[0] = true;
		
		while(stack.isEmpty() == false) {
			int node = stack.pop();
			
			System.out.print(node + " ");
			
			for (int j = 0; j<count; j++) {
				if(matrix[node][j] != 0 && !visited[j]) {
					stack.push(j);
					visited[j] = true;
				}
			}
		}
	}
	
	public static void main(String[] args) {
		int count = 0;
		UndirectedGraph graph = new UndirectedGraph(count);
		DfsSearch dfsSearch = new DfsSearch(count);
		
		graph.addEdges(0,1,1);
		
		dfsSearch.matrix = graph.getMatrix();
		dfsSearch.dfsTraversal();
	}
}

3. DFS로 2차원 배열 영역 개수 및 크기 구하기

DFS(깊이 우선 탐색, Depth First Search)는 그래프나 2차원 배열에서 연결된 노드를 탐색할 때 자주 사용되는 알고리즘입니다.

이 예제는 2차원 배열에서 1로 연결된 영역을 DFS로 탐색하여, 전체 영역의 개수와 각 영역의 크기를 구하는 문제입니다.

map = new int[][] {
    {1, 1, 0, 0, 0},
    {1, 1, 0, 1, 1},
    {0, 0, 0, 1, 1},
    {0, 1, 1, 0, 0}
};

여기서 1은 영역의 일부, 0은 빈 공간을 의미합니다. 인접한 1들(상, 하, 좌, 우로 연결된 것들)은 하나의 영역으로 간주됩니다. 이 배열에서 총 몇 개의 영역이 있는지, 각 영역의 크기는 얼마나 되는지를 구하고자 합니다.

DFS 탐색 원리

  • 방문 여부를 기록하는 visited 배열을 사용해 중복 방문을 방지합니다.
  • 상하좌우로 이동 가능한 방향 벡터를 정의합니다.
  • dfs(x, y) 함수는 현재 위치에서 상하좌우를 탐색하며 연결된 모든 1을 방문 처리합니다.
  • main() 함수에서는 전체 배열을 순회하며 방문하지 않은 1을 만나면 새 영역의 시작으로 보고 DFS를 실행합니다.
import java.util.*;

public class Main {
    static int[][] map;
    static boolean[][] visited;
    static int n, m;
    static int areaSize;

    // 방향벡터: 상하좌우
    static int[] dx = {-1, 1, 0, 0};
    static int[] dy = {0, 0, -1, 1};

    public static void main(String[] args) {
        map = new int[][] {
            {1, 1, 0, 0, 0},
            {1, 1, 0, 1, 1},
            {0, 0, 0, 1, 1},
            {0, 1, 1, 0, 0}
        };

        n = map.length;
        m = map[0].length;
        visited = new boolean[n][m];

        int regionCount = 0;
        List<Integer> areaSizes = new ArrayList<>();

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (!visited[i][j] && map[i][j] == 1) {
                    areaSize = 0;
                    dfs(i, j);
                    regionCount++;
                    areaSizes.add(areaSize);
                }
            }
        }

        System.out.println("영역 개수: " + regionCount);
        System.out.println("각 영역 크기: " + areaSizes);
    }

    public static void dfs(int x, int y) {
        visited[x][y] = true;
        areaSize++;

        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];

            if (nx >= 0 && ny >= 0 && nx < n && ny < m) {
                if (!visited[nx][ny] && map[nx][ny] == 1) {
                    dfs(nx, ny);
                }
            }
        }
    }
}