알고리즘, SQL/알고리즘

깊이 우선 탐색/DFS 알고리즘이란?

킹갓홍 2023. 12. 29. 00:01

지난 포스팅에서 DFS와 BFS알고리즘을 알아보기 위해 그래프 자료구조를 선행하여 정리했다.

https://hsch19.tistory.com/39

 

그래프(Graph) 자료구조란 무엇인가?

개요 DFS와 BFS에 대해서 정리를 해보려고 정리하던 중 그래프 자료구조에 대한 정리가 선행되어야 할 것 같아서 그래프 자료구조에 대해 먼저 정리하고자 한다. 그래프(Graph) 자료구조란? 그래프

hsch19.tistory.com

 

DFS 알고리즘이란?

DFS는 Depth-First  Search의 약자로 깊이 우선 탐색이라고도 불린다.

DFS는 트리나 그래프를 탐색하는 기법 중 하나로, 시작노드에서 자식의 노드들을 순서대로 탐색하면서 깊이를 우선으로 탐색하는 알고리즘이다.

비유하자면, DFS는 미로 탐색시 한 방향으로 모든 노드를 방문하다가 더 이상 방문할 노드가 없다면 가장 가까운 갈래길로 돌아가 방문하지 않은 노드 방향으로 탐색을 이어가는 것이다.

 

DFS의 특징

  • 재귀나 스택을 이용해 자기 자신을 호출하는 형태이다.
  • 탐색 시 노드를 방문하면 반드시 방문여부를 체크해야 한다.(이를 검사하지 않으면 무한루프에 빠질 수 있음)
  • 그래프에서 간선이나 변수 정보를 수시로 변경해야하는 문제에서 효과적이다.

DFS 과정

https://gmlwjd9405.github.io/2018/08/14/algorithm-dfs.html

너비가 아닌 깊이를 우선적으로 탐색했기 때문에 0 - 1 - 2 - 3 - 4라는 경로로 탐색하는 것을 볼 수 있다.

 

DFS의 장점

  1. 스택을 사용해서 DFS 구현시 현재 순회중인 노드만 저장하기 때문에 BFS에 비해 메모리 공간을 덜 차지한다.
  2. DFS는 목표가 특정 노드 또는 모든 노든에 최대한 빠르게 도달할 때 유용하다.

DFS의 단점

  1. DFS를 통해 얻어진 해가 최단 경로라는 보장이 없다.
  2. 만약, 답이 아닌 경로가 매우 깊다면 그 경로로 깊이 빠질 수 있다.

기초예제

https://www.acmicpc.net/problem/2606

 

2606번: 바이러스

첫째 줄에는 컴퓨터의 수가 주어진다. 컴퓨터의 수는 100 이하인 양의 정수이고 각 컴퓨터에는 1번 부터 차례대로 번호가 매겨진다. 둘째 줄에는 네트워크 상에서 직접 연결되어 있는 컴퓨터 쌍

www.acmicpc.net

재귀호출을 사용한 DFS풀이 방법

public class Main {
    static int Node;
    static int Line;
    static int[][] map;
    static boolean[] visited;
    static int count = 0;

    public static void main(String args[]) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        Node = Integer.parseInt(br.readLine());
        Line = Integer.parseInt(br.readLine());

        map = new int [Node+1][Node+1]; //배열은 0부터 시작하지만 노드는 1부터 시작하기 때문에
        visited = new boolean[Node+1];//착오를 줄이기 위해 0은 버리고 1부터 저장한다.
        count = 0;

        for(int i=0; i<Line; i++) {
            StringTokenizer st = new StringTokenizer(br.readLine()," ");
            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());

            map[a][b] = 1; //무방향 그래프는 A-B 와 B-A가 같다.
            map[b][a] = 1;
        }

        dfs(1);
        System.out.println(count-1);

    }//end main

    public static void dfs(int start) {
        visited[start] = true;
        count++;
            for(int i=0; i<=Node; i++) {
                if(map[start][i]==1 && visited[i]!=true) { //간선이 존재하고, 방문하지 않았다면,
                    dfs(i); //재귀호출을 해준다.
                }
            }	
    }//end dfs
	
}//end class

 

 


참고자료

https://heytech.tistory.com/55

https://infodon.tistory.com/97

https://developmentnotepad.tistory.com/entry/Algorithm-DFS-BFS

https://olrlobt.tistory.com/35

https://gmlwjd9405.github.io/2018/08/14/algorithm-dfs.html