ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 깊이 우선 탐색(DFS) 란?
    Computer Science/Data_Structure 2020. 1. 4. 00:36
    728x90
    반응형

    그래프의 탐색

    그래프 탐색은 가장 기본적인 연산으로서 하나의 정점으로부터 시작하여 차례대로 모든 정점들을 한 번씩 방문하는 것이다. 그래프 탐색은 아주 중요하다 

     

    • 도시를 연결하는 그래프가 있을 때, 특정 도시에서 다른 도시로 갈 수 있는지 없는지는 탐색하여 체크

     

    그래프의 탐색 방법은 깊이 우선 탐색너비 우선 탐색의 두 가지가 있다.

    이 글에서는 깊이 우선 탐색에 대하여 알아보겠다.

     

     

     

    깊이 우선탐색(DFS : depth first search) 

    • 트리에서 생각하면 이해하기 쉽다(트리도 그래프의 일종이라는 점을 명심하자)

    • 트리를 탐색할 때 시작 정점에서 한 방향으로 계속 가다가 더 이상 갈 수 없게 되면 다시 가장 가까운 갈림길로 돌아와서 다른 방향으로 다시 탐색을 진행하는 방법과 유사

     

     

    위와 같은 그림의 그래프 처럼 탐색을 하는 것이 DFS 탐색이라고 할 수 있다.  그러면 진행되는 과정을 자세히 한번 공부해보려 한다.

     

     

    DFS 탐색은 어디에서 사용될까? 

    미로 탐색에 사용된다. 

    • 미로 탐색시 한 방향으로 갈 수 있을 때까지 계속 탐색.

    • 모든 노드를 방문하고자 하는 경우에 사용

     

     

     

    그래프에서 깊이 우선 탐색은 어떻게 진행될까?

    • 깊이 우선 탐색은 그래프의 시작 정점에서 출발하여 시작 정점 0을 방문하였다고 표시

    • 이어서 v에 인접한 정점들 중에서 아직 방문하지 않은 정점 1을 선택한다.

    • 그리고 만약 그러한 정점이 없다면 탐색은 종료한다. 

    • 만약 아직 방문하지 않은 정점이 남아 있다면 그 정점을 시작으로 하여 탐색을 다시 시작한다.

    • 깊이 우선 탐색도 자기 자신을 다시 호출하는 순환 알고리즘의 형태를 가지고 있다.

     

     

    깊이 우선 탐색의 구현(인접 행렬)

    깊이 우선 탐색을 구현하는 데는 2가지의 방법이 있다. 

    • 첫 번째 : 순환 호출을 이용

    • 두 번째 : 명시적인 스택을 이용 

     

    이번에는 자바를 이용해서 순환 호출을 이용하는 방법으로 구현해보려고 한다. 

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    import java.util.LinkedList;
     
    public class Graph {
        public int V;   //노드의 개수
        public LinkedList<Integer>[] adj;  //인접 리스트
        boolean[] visited;
     
        //생성자
        public Graph(int v){
            V = v;
            adj = new LinkedList[v];
            visited = new boolean[V];
     
            for(int i=0; i<v; i++){
                adj[i] = new LinkedList();
            }
        }
     
        void addEdge(int v, int w){
            adj[v].add(w);
        }
     
        void DFS(int v){   //순환 호출을 이용해서 구현
            visited[v] = true;
            System.out.print(v + " ");
     
            for(int k : adj[v]){
                if(!visited[k]){
                    DFS(k);     //순환 호출
                }
            }
     
        }
    }
     
     
     

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
      
    package Data_Structure.DFS;
     
    public class Test {
        public static void main(String[] args){
            Graph g = new Graph(4);
     
            g.addEdge(0,1);
            g.addEdge(0,2);
            g.addEdge(1,2);
            g.addEdge(2,0);
            g.addEdge(2,3);
            g.addEdge(3,3);
     
            g.DFS(2);
     
     
        }
    }
     
     

     

    위와 같이 순환호출을 이용해서 DFS를 구현하였다. 그리고 DFS 공부를 했는데 어느정도 어떤 탐색인지는 알겠지만 아직 응용은 안될 것 같다. 열심히 공부해야지 

     

     

     

    깊이 우선 탐색의 분석

    깊이 우선 탐색은 그래프의 모든 간선을 조사하므로 정점의 수가 n이고 간선의 수가 e인 그래프인 경우, 그래프가 인접 리스트로 표현되어 있다면 시간 복잡도가 O(n+e)이고, 인접 행렬로 표시되어 있다면 O(n*n)이다.

     

    이는 희소 그래프인 경우 깊이 우선 탐색은 인접 리스트의 사용이 인접 행렬보다 시간적으로 유리함을 뜻한다. 

    반응형

    'Computer Science > Data_Structure' 카테고리의 다른 글

    그래프(graph)의 구현 2가지  (0) 2020.01.04
    너비 우선 탐색(BFS) 란?  (0) 2020.01.04
    그래프(Graph) 란?  (0) 2020.01.03
    힙(heap) 이란 ?  (0) 2020.01.03
    이진 탐색 트리(binary search tree) 란?  (0) 2020.01.02

    댓글

Designed by Tistory.