[자료구조] 그래프

1 minute read

그래프

  • 그래프는 단순히 노드와 그 노드를 연결하는 간선(edge)을 하나로 모아 놓은 것.
  • 트리는 그래프의 한 종류.
  • 방향성이 있을 수도 없을 수도 있다.
  • 사이클이 존재할 수도 존재하지 않을 수도 있다.

그래프 탐색

그래프에서 모든 노드를 방문하고자 할 때 더 선호되는 편이다. 둘 중 아무거나 사용해도 상관없지만, 깊이 우선 탐색이 좀 더 간단하긴 하다.
전위 순회를 포함한 다른 형태의 트리 순회는 모두 DFS의 한 종류이다.
그래프 탐색의 경우 어떤 노드를 방문했었는지 여부를 반드시 검사해야 한다는 것이 큰 차이점이다. 검사하지 않을 경우 무한 루프에 빠질 위험이 있다.

//DFS 의사코드

void searchDFS(Node root){
  if(root == null) return;
  visit(root);
  root.visited = true;
  for each(Node n in root.adjacent){
    if(n.visited == false){
      searchDFS(n);
    }
  }
}

두 노드 사이의 최단 경로 혹은 임의의 경로를 찾고 싶을 때는 너비 우선 탐색이 더 낫다.
BFS는 직관적이지 않은 면이 있다.
실패하는 가장 흔한 이유는 BFS가 재귀적으로 동작할 거라고 잘못 가정하는 것이다.
BFS는 큐(Queue)를 이용해서 반복적 형태로 구현하는 것이 가장 잘 동작한다.

//BFS 의사코드

void searchBFS(Node root){
  Queue queue = new Queue();
  root.marked = true;
  queue.enqueue(root);

  while(!queue.isEmpty()){
    Node r = queue.dequeue();
    visit(r);
    for each (Node n in r.adjacent){
      if(n.marked == false){
        n.marked = true;
        queue.enqueue(n);
      }
    }
  }
}

양방향 탐색

양방향 탐색은 출발지와 도착지 사이에 최단 경로를 찾을 때 사용되곤 한다. 기본적으로 출발지와 도착지 두 노드에서 동시에 너비 우선 탐색을 수행한 뒤, 두 탐색 지점이 충돌하는 경우에 경로를 찾는 방식이다.