12. DFS BFS - bloodfinger8/AlgorithmStudy GitHub Wiki

DFS

1. DFS๋ž€?

dfs
๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰(Deep-first search)๋ž€ ํƒ์ƒ‰ํŠธ๋ฆฌ์˜ ์ตœ๊ทผ์— ์ฒจ๊ฐ€๋œ ๋…ธ๋“œ๋ฅผ ์„ ํƒํ•˜๊ณ , ์ด ๋…ธ๋“œ์— ์ ์šฉ ๊ฐ€๋Šฅํ•œ ๋™์ž‘์ž ์ค‘ ํ•˜๋‚˜๋ฅผ ์ ์šฉํ•˜์—ฌ ํŠธ๋ฆฌ์— ๋‹ค์Œ ์ˆ˜์ค€(level)์˜ ํ•œ ๊ฐœ์˜ ์ž์‹๋…ธ๋“œ๋ฅผ ์ฒจ๊ฐ€ํ•˜๋ฉฐ, ์ฒจ๊ฐ€๋œ ์ž์‹ ๋…ธ๋“œ๊ฐ€ ๋ชฉํ‘œ๋…ธ๋“œ์ผ ๋•Œ๊นŒ์ง€ ์•ž์˜ ์ž์‹ ๋…ธ๋“œ์˜ ์ฒจ๊ฐ€ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•ด ๊ฐ€๋Š” ๋ฐฉ์‹์ด๋‹ค.

์žฅ์ 

  • ๋‹จ์ง€ ํ˜„ ๊ฒฝ๋กœ์ƒ์˜ ๋…ธ๋“œ๋“ค๋งŒ์„ ๊ธฐ์–ตํ•˜๋ฉด ๋˜๋ฏ€๋กœ ์ €์žฅ๊ณต๊ฐ„์˜ ์ˆ˜์š”๊ฐ€ ๋น„๊ต์  ์ ๋‹ค.
  • ๋ชฉํ‘œ๋…ธ๋“œ๊ฐ€ ๊นŠ์€ ๋‹จ๊ณ„์— ์žˆ์„ ๊ฒฝ์šฐ ํ•ด๋ฅผ ๋นจ๋ฆฌ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹จ์ 

  • ํ•ด๊ฐ€ ์—†๋Š” ๊ฒฝ๋กœ์— ๊นŠ์ด ๋น ์งˆ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‹ค์ œ์˜ ๊ฒฝ์šฐ ๋ฏธ๋ฆฌ ์ง€์ •ํ•œ ์ž„์˜์˜ ๊นŠ์ด๊นŒ์ง€๋งŒ ํƒ์ƒ‰ํ•˜๊ณ  ๋ชฉํ‘œ๋…ธ๋“œ๋ฅผ ๋ฐœ๊ฒฌํ•˜์ง€ ๋ชปํ•˜๋ฉด ๋‹ค์Œ์˜ ๊ฒฝ๋กœ๋ฅผ ๋”ฐ๋ผ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์œ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์–ป์–ด์ง„ ํ•ด๊ฐ€ ์ตœ๋‹จ ๊ฒฝ๋กœ๊ฐ€ ๋œ๋‹ค๋Š” ๋ณด์žฅ์ด ์—†๋‹ค. ์ด๋Š” ๋ชฉํ‘œ์— ์ด๋ฅด๋Š” ๊ฒฝ๋กœ๊ฐ€ ๋‹ค์ˆ˜์ธ ๋ฌธ์ œ์— ๋Œ€ํ•ด ๊นŠ์ด์šฐ์„  ํƒ์ƒ‰์€ ํ•ด์— ๋‹ค๋‹ค๋ฅด๋ฉด ํƒ์ƒ‰์„ ๋๋‚ด๋ฒ„๋ฆฌ๋ฏ€๋กœ, ์ด๋•Œ ์–ป์–ด์ง„ ํ•ด๋Š” ์ตœ์ ์ด ์•„๋‹ ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

2. DFS ๊ตฌํ˜„ ์˜ˆ์‹œ

class Graph {
  private int V;   // ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜
  private LinkedList<Integer> adj[]; // ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ

  /** ์ƒ์„ฑ์ž */
  Graph(int v) {
      V = v;
      adj = new LinkedList[v];
      for (int i=0; i<v; ++i) // ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ์ดˆ๊ธฐํ™”
          adj[i] = new LinkedList();
  }

  /** ๋…ธ๋“œ๋ฅผ ์—ฐ๊ฒฐ v->w */
  void addEdge(int v, int w) { adj[v].add(w); }

  /** DFS์— ์˜ํ•ด ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜ */
  void DFSUtil(int v, boolean visited[]) {
      // ํ˜„์žฌ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•œ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œํ•˜๊ณ  ๊ฐ’์„ ์ถœ๋ ฅ
      visited[v] = true;
      System.out.print(v + " ");

      // ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ์™€ ์ธ์ ‘ํ•œ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
      Iterator<Integer> i = adj[v].listIterator();
      while (i.hasNext()) {
          int n = i.next();
          // ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๋ฉด ํ•ด๋‹น ๋…ธ๋“œ๋ฅผ ์‹œ์ž‘ ๋…ธ๋“œ๋กœ ๋‹ค์‹œ DFSUtil ํ˜ธ์ถœ
          if (!visited[n])
              DFSUtil(n, visited); // ์ˆœํ™˜ ํ˜ธ์ถœ
      }
  }

  /** ์ฃผ์–ด์ง„ ๋…ธ๋“œ๋ฅผ ์‹œ์ž‘ ๋…ธ๋“œ๋กœ DFS ํƒ์ƒ‰ */
  void DFS(int v) {
      // ๋…ธ๋“œ์˜ ๋ฐฉ๋ฌธ ์—ฌ๋ถ€ ํŒ๋‹จ (์ดˆ๊นƒ๊ฐ’: false)
      boolean visited[] = new boolean[V];

      // v๋ฅผ ์‹œ์ž‘ ๋…ธ๋“œ๋กœ DFSUtil ์ˆœํ™˜ ํ˜ธ์ถœ
      DFSUtil(v, visited);
  }

  /** DFS ํƒ์ƒ‰ */
  void DFS() {
      // ๋…ธ๋“œ์˜ ๋ฐฉ๋ฌธ ์—ฌ๋ถ€ ํŒ๋‹จ (์ดˆ๊ธฐ๊ฐ’: false)
      boolean visited[] = new boolean[V];

      // ๋น„์—ฐ๊ฒฐํ˜• ๊ทธ๋ž˜ํ”„์˜ ๊ฒฝ์šฐ, ๋ชจ๋“  ์ •์ ์„ ํ•˜๋‚˜์”ฉ ๋ฐฉ๋ฌธ
      for (int i=0; i<V; ++i) {
          if (visited[i] == false)
              DFSUtil(i, visited);
      }
  }
}

BFS

1. BFS๋ž€?

bfs
๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰(Breadth-first search)๋ž€ ์‹œ์ž‘ ์ •์ ์„ ๋ฐฉ๋ฌธํ•œ ํ›„ ์‹œ์ž‘ ์ •์ ์— ์ธ์ ‘ํ•œ ๋ชจ๋“  ์ •์ ๋“ค์„ ์šฐ์„  ๋ฐฉ๋ฌธํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ๋” ์ด์ƒ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ์ •์ ์ด ์—†์„ ๋•Œ๊นŒ์ง€ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋ชจ๋“  ์ •์ ๋“ค์— ๋Œ€ํ•ด์„œ๋„ ๋„ˆ๋น„ ์šฐ์„  ๊ฒ€์ƒ‰์„ ์ ์šฉํ•œ๋‹ค.

์žฅ์ 

  • ์ถœ๋ฐœ๋…ธ๋“œ์—์„œ ๋ชฉํ‘œ๋…ธ๋“œ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ธธ์ด ๊ฒฝ๋กœ๋ฅผ ๋ณด์žฅํ•œ๋‹ค.

๋‹จ์ 

  • ๊ฒฝ๋กœ๊ฐ€ ๋งค์šฐ ๊ธธ ๊ฒฝ์šฐ์—๋Š” ํƒ์ƒ‰ ๊ฐ€์ง€๊ฐ€ ๊ธ‰๊ฒฉํžˆ ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ ๋ณด๋‹ค ๋งŽ์€ ๊ธฐ์–ต ๊ณต๊ฐ„์„ ํ•„์š”๋กœ ํ•˜๊ฒŒ ๋œ๋‹ค.
  • ํ•ด๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์œ ํ•œ ๊ทธ๋ž˜ํ”„(finite graph)์˜ ๊ฒฝ์šฐ์—๋Š” ๋ชจ๋“  ๊ทธ๋ž˜ํ”„๋ฅผ ํƒ์ƒ‰ํ•œ ํ›„์— ์‹คํŒจ๋กœ ๋๋‚œ๋‹ค.
  • ๋ฌดํ•œ ๊ทธ๋ž˜ํ”„(infinite graph)์˜ ๊ฒฝ์šฐ์—๋Š” ๊ฒฐ์ฝ” ํ•ด๋ฅผ ์ฐพ์ง€๋„ ๋ชปํ•˜๊ณ , ๋๋‚ด์ง€๋„ ๋ชปํ•œ๋‹ค.

2. BFS ๊ตฌํ˜„ ์˜ˆ์‹œ

Class Graph {
  private int V; // ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜
  private LinkedList<Integer> adj[]; // ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ

  /** ์ƒ์„ฑ์ž */
  Graph(int v) {
    V = v;
    adj = new LinkedList[v];
    for (int i=0; i<v; ++i) // ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ์ดˆ๊ธฐํ™”
      adj[i] = new LinkedList();
  }

  /** ๋…ธ๋“œ๋ฅผ ์—ฐ๊ฒฐ v->w */
  void addEdge(int v, int w) { adj[v].add(w); }

  /** s๋ฅผ ์‹œ์ž‘ ๋…ธ๋“œ์œผ๋กœ ํ•œ BFS๋กœ ํƒ์ƒ‰ํ•˜๋ฉด์„œ ํƒ์ƒ‰ํ•œ ๋…ธ๋“œ๋“ค์„ ์ถœ๋ ฅ */
  void BFS(int s) {
    // ๋…ธ๋“œ์˜ ๋ฐฉ๋ฌธ ์—ฌ๋ถ€ ํŒ๋‹จ (์ดˆ๊นƒ๊ฐ’: false)
    boolean visited[] = new boolean[V];
    // BFS ๊ตฌํ˜„์„ ์œ„ํ•œ ํ(Queue) ์ƒ์„ฑ
    LinkedList<Integer> queue = new LinkedList<Integer>();

    // ํ˜„์žฌ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•œ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œํ•˜๊ณ  ํ์— ์‚ฝ์ž…(enqueue)
    visited[s] = true;
    queue.add(s);

    // ํ(Queue)๊ฐ€ ๋นŒ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต
    while (queue.size() != 0) {
      // ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ํ์—์„œ ์ถ”์ถœ(dequeue)ํ•˜๊ณ  ๊ฐ’์„ ์ถœ๋ ฅ
      s = queue.poll();
      System.out.print(s + " ");

      // ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ์™€ ์ธ์ ‘ํ•œ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
      Iterator<Integer> i = adj[s].listIterator();
      while (i.hasNext()) {
        int n = i.next();
        // ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๋ฉด ๋ฐฉ๋ฌธํ•œ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œํ•˜๊ณ  ํ์— ์‚ฝ์ž…(enqueue)
        if (!visited[n]) {
          visited[n] = true;
          queue.add(n);
        }
      }
    }
  }
}
โš ๏ธ **GitHub.com Fallback** โš ๏ธ