DFS/ BFS

๐Ÿ”‘๋Œ€ํ‘œ์  ๊ทธ๋ž˜ํ”„(Graph) ํƒ์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ธ DFS/BFS๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜ํ”„(Graph)๋Š” ๋ญ˜๊นŒ?

  • ๊ทธ๋ž˜ํ”„(Graph) ๋Š” ์ •์ (vertex, ๋…ธ๋“œ)๊ณผ ๊ฐ„์„ (edge)๋กœ ๊ตฌ์„ฑ๋œ ์œ ํ•œํ•œ(finite) ์ž๋ฃŒ๊ตฌ์กฐ ์ž…๋‹ˆ๋‹ค.

  • ๋‘ ์ •์ (๋…ธ๋“œ)๊ฐ€ ๊ฐ„์„ ์œผ๋กœ ์—ฐ๊ฒฐ๋˜๋ฉด '๋‘ ๋…ธ๋“œ๋Š” ์ธ์ ‘(Adjacent)ํ•˜๋‹ค' ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

Graph

  • ํŽ˜์ด์Šค๋ถ, ์ธ์Šคํƒ€๊ทธ๋žจ ๊ฐ™์€ ์†Œ์…œ ๋„คํŠธ์›Œํฌ์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ๊ทธ๋ž˜ํ”„ ๊ตฌ์กฐ๋กœ ๋งŒ๋“ค์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜ํ”„ ๊ตฌ์กฐ๋ฅผ ํ†ตํ•ด ์‚ฌ๋žŒ๋“ค(node) ์‚ฌ์ด์˜ ๊ด€๊ณ„(edge) ๋ฅผ ์‰ฝ๊ฒŒ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    Graph - Social Network

๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰

  • ํ•˜๋‚˜์˜ ์ •์ (๋…ธ๋“œ)์—์„œ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ํ•œ ๋ฒˆ์”ฉ ํƒ์ƒ‰(๋ฐฉ๋ฌธ) ํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

  • ๊ทธ๋ž˜ํ”„์˜ ์ตœ๋Œ€ ๊นŠ์ด๊นŒ์ง€ ํƒ์ƒ‰ํ•œ ํ›„, ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋กœ ์ด๋™ํ•˜์—ฌ ํƒ์ƒ‰ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค.

    • ์‹œ์ž‘ ๋…ธ๋“œ์—์„œ ์ตœ๋Œ€ํ•œ ๋ฉ€๋ฆฌ ์žˆ๋Š” ๋…ธ๋“œ ๋ฅผ ์šฐ์„  ํƒ์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

      Depth-First-Search

  • DFS๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฏธ๋กœ์ฐพ๊ธฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฏธ๋กœ ์†์˜ ๊ธธ์„ ๊ฐ„์„ (edge)์œผ๋กœ, ๋ง‰๋‹ค๋ฅธ ์ง€์ ์„ ์ •์ (node)์œผ๋กœ ๋ณด๊ณ  ๋ฏธ๋กœ์˜ ๋„์ฐฉ์ ์— ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ ๊ฐ ๊ฒฝ๋กœ์˜ ์ตœ๋Œ€ ๊นŠ์ด๊นŒ์ง€ ํƒ์ƒ‰ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ์„ ํƒํ•œ ๊ฒฝ๋กœ๊ฐ€ ๋ง‰๋‹ค๋ฅธ ๊ณจ๋ชฉ์— ๋ถ€๋”ชํžˆ๋ฉด ๋˜๋Œ์•„๊ฐ€์„œ(๋ฐฑํŠธ๋ž˜ํ‚น) ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

    maze - DFS

  • ์Šคํƒ๊ณผ ์žฌ๊ท€ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • DFS ๊ตฌํ˜„ ์˜ˆ์‹œ

    class Graph {
      constructor() {
        this.adjacencyList = {};
      }
      // ์ •์ (๋…ธ๋“œ) ์ถ”๊ฐ€
      addVertex(vertex) {
        if (!this.adjacencyList[vertex]) this.adjacencyList[vertex] = [];
        return this.adjacencyList;
      }
      // ๊ฐ„์„  ์ถ”๊ฐ€
      addEdge(vertex1, vertex2) {
        this.adjacencyList[vertex1].push(vertex2);
        this.adjacencyList[vertex2].push(vertex1);
        return this.adjacencyList;
      }
    
      // ํƒ์ƒ‰ ์‹œ์ž‘ ๋…ธ๋“œ ์ธ์ž
      DFS(start) {
        const result = []; // ํƒ์ƒ‰ ๊ฒฐ๊ณผ ๋ฐฐ์—ด
        const visited = {}; // ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ ์ฒดํฌ(๊ฐ ๋…ธ๋“œ๋ฅผ ํ•œ ๋ฒˆ์”ฉ๋งŒ ์ฒ˜๋ฆฌํ•˜๋„๋ก)
        const adjacencyList = this.adjacencyList;
    
        function dfs(vertex) {
          // ์ •์ ์ด ๋นˆ ๊ฐ’์ด๋ฉด null์„ ๋ฐ˜ํ™˜
          if (!vertex) return null;
          // ์‹œ์ž‘ ๋…ธ๋“œ๋ฅผ ์Šคํƒ์— pushํ•˜๊ณ  ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ
          visited[vertex] = true;
          // ํƒ์ƒ‰ ๊ฒฐ๊ณผ ๋ฐฐ์—ด์— ๋…ธ๋“œ push
          result.push(vertex);
          // ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ ํ˜„์žฌ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋‹ค๋ฅธ ๋…ธ๋“œ ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ
          adjacencyList[vertex].forEach((v) => {
            // ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ์ธ์ ‘ ๋…ธ๋“œ ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ(์žฌ๊ท€)
            if (!visited[v]) dfs(v);
          });
        }
        dfs(start);
        return result;
      }
    }
    const graph = new Graph();
    graph.addVertex("A");
    graph.addVertex("B");
    graph.addVertex("C");
    graph.addVertex("D");
    graph.addVertex("E");
    graph.addVertex("F");
    
    graph.addEdge("A", "B");
    graph.addEdge("A", "C");
    graph.addEdge("B", "D");
    graph.addEdge("C", "E");
    graph.addEdge("D", "E");
    graph.addEdge("D", "F");
    graph.addEdge("E", "F");
    
    graph.DFS("A")  //  ["A", "B", "D", "E", "C", "F"]
  • ๊ทธ๋ž˜ํ”„์˜ ๊ทผ์ ‘ ๋…ธ๋“œ๋ถ€ํ„ฐ ํƒ์ƒ‰ํ•œ ํ›„, ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋กœ ์ด๋™ํ•˜์—ฌ ํƒ์ƒ‰ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค.

    • ์‹œ์ž‘ ๋…ธ๋“œ์—์„œ ์ตœ๋Œ€ํ•œ ๊ฐ€๊นŒ์šด ๋…ธ๋“œ(์ด์›ƒ ๋…ธ๋“œ) ๋ถ€ํ„ฐ ์šฐ์„  ํƒ์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.

      Breadth-First-Search

    • BFS๋Š” P2P ํŒŒ์ผ ๋„คํŠธ์›Œํฌ์—์„œ ํ”ผ์–ด(peer) ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ํ•  ๋•Œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. BFS๋ฅผ ํ™œ์šฉํ•ด ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ด์›ƒ ๋…ธ๋“œ๋งŒ ๋น ๋ฅด๊ฒŒ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

      P2P - BFS

  • ํ๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • BFS ๊ตฌํ˜„ ์˜ˆ์‹œ

    class Graph {
      constructor() {
        this.adjacencyList = {};
      }
      // ์ •์ (๋…ธ๋“œ) ์ถ”๊ฐ€
      addVertex(vertex) {
        if (!this.adjacencyList[vertex]) this.adjacencyList[vertex] = [];
        return this.adjacencyList;
      }
      // ๊ฐ„์„  ์ถ”๊ฐ€
      addEdge(vertex1, vertex2) {
        this.adjacencyList[vertex1].push(vertex2);
        this.adjacencyList[vertex2].push(vertex1);
        return this.adjacencyList;
      }
    
      BFS(start) {
        const result = [];
        const visited = {};
        let vertex; // ํ˜„์žฌ ๋…ธ๋“œ
        const adjacencyList = this.adjacencyList;
        // ํƒ์ƒ‰ ์‹œ์ž‘ ๋…ธ๋“œ๋ฅผ ํ์— ๋„ฃ๊ณ , ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ
        const queue = [start];
        visited[start] = true;
        // ํ๊ฐ€ ๋น„์–ด์žˆ์„ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต
        while (queue.length) {
          // console.log(queue);
          vertex = queue.shift(); // 
          result.push(vertex);
          // ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜์—ฌ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ์ธ์ ‘ ๋…ธ๋“œ
          // ํ์— pushํ•˜๊ณ , ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ
          adjacencyList[vertex].forEach((v) => {
            if (!visited[v]) {
              queue.push(v); 
              visited[v] = true;
            }
          });
        }
        return result;
      }
    }
    const graph = new Graph();
    graph.addVertex("A");
    graph.addVertex("B");
    graph.addVertex("C");
    graph.addVertex("D");
    graph.addVertex("E");
    graph.addVertex("F");
    
    graph.addEdge("A", "B");
    graph.addEdge("A", "C");
    graph.addEdge("B", "D");
    graph.addEdge("C", "E");
    graph.addEdge("D", "E");
    graph.addEdge("D", "F");
    graph.addEdge("E", "F");
    
    graph.BFS("A")  //   ["A", "B", "C", "D", "E", "F"]

    โ€ป Big-O

    • ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” ๋‘ ํƒ์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ชจ๋‘ O(N) (N: ๊ทธ๋ž˜ํ”„ ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜) ์ž…๋‹ˆ๋‹ค.

    • ๊ณต๊ฐ„ ๋ณต์žก๋„๋Š” DFS๋ณด๋‹ค BFS ์ƒ๋Œ€์ ์œผ๋กœ ํฝ๋‹ˆ๋‹ค.(๋” ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ ์ฐจ์ง€)

๐Ÿ’ก์ •๋ฆฌ

ํ•ญ๋ชฉ

DFS

BFS

์ˆœํšŒ

๊นŠ์ด

๋„“์ด

์ž๋ฃŒ๊ตฌ์กฐ

์Šคํƒ(LIFO)

ํ(FIFO)

์ตœ์ ํ™”

โŒ

โญ•๏ธ

๋ฌดํ•œ๋ฃจํ”„

โญ•๏ธ

โŒ

ํŠน์ง•

๋ฐฑํŠธ๋ž˜ํ‚น

์ตœ์ ํ™”

  • BFS๋Š” ํƒ์ƒ‰ํ•ด์•ผ ํ•  ๊ทธ๋ž˜ํ”„์˜ ๊นŠ์ด๊ฐ€ ๋…ธ๋“œ๋งˆ๋‹ค ๋‹ค๋ฅด๊ฑฐ๋‚˜ ๋‹จ์ผ ๋Œ€๋‹ต์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ(์ตœ๋‹จ ๊ฒฝ๋กœ ๊ตฌํ•˜๊ธฐ ๋“ฑ)์— ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • ๊ทธ๋ž˜ํ”„์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ํƒ์ƒ‰ํ•ด์•ผ ํ•œ๋‹ค๋ฉด DFS๊ฐ€ ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Reference

Graph | AWS

Graphs: breadth-first search | freeCodeCamp

Graphs: depth-first search | brilliant

Algorithm Visualizer

DFS์™€ BFS์˜ ์ฐจ์ด

BFS๋กœ ์ตœ๋‹จ๊ฑฐ๋ฆฌ ์ฐพ๊ธฐ | freeCodeCamp

Last updated