๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
์•Œ๊ณ ๋ฆฌ์ฆ˜

[๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰] ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰(Depth First Search, DFS)

by ์„œ์•„๋ž‘๐Ÿ˜ 2025. 2. 12.

 

 

๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰(Depth-First Search, DFS)

๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰(DFS)์€ ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ค‘ ํ•˜๋‚˜๋กœ, ํ•œ ์ •์ ์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ๊ฐ€๋Šฅํ•œ ๊นŠ์ด๊นŒ์ง€ ํƒ์ƒ‰ํ•œ ํ›„, ๋” ์ด์ƒ ๊ฐˆ ๊ณณ์ด ์—†์œผ๋ฉด ๋˜๋Œ์•„์˜ค๋Š” ๋ฐฉ์‹(๋ฐฑํŠธ๋ž˜ํ‚น)์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ”น DFS ๊ฐœ๋…

DFS๋Š” ์Šคํƒ(์žฌ๊ท€ ํ˜ธ์ถœ or ๋ช…์‹œ์  ์Šคํƒ)์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ๋ž˜ํ”„๋ฅผ ๊นŠ๊ฒŒ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

  • ๋จผ์ € ํ˜„์žฌ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ณ ,
  • ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ์ธ์ ‘ ๋…ธ๋“œ๊ฐ€ ์žˆ์œผ๋ฉด ํ•ด๋‹น ๋…ธ๋“œ๋กœ ์ด๋™ํ•˜์—ฌ ํƒ์ƒ‰์„ ๊ณ„์†ํ•จ.
  • ๋” ์ด์ƒ ๋ฐฉ๋ฌธํ•  ๋…ธ๋“œ๊ฐ€ ์—†์œผ๋ฉด ์ด์ „ ๋…ธ๋“œ(๋ถ€๋ชจ ๋…ธ๋“œ)๋กœ ๋Œ์•„๊ฐ(๋ฐฑํŠธ๋ž˜ํ‚น).

๐Ÿ”น DFS ๋™์ž‘ ๋ฐฉ์‹

DFS์˜ ๊ธฐ๋ณธ ๋™์ž‘ ์ˆœ์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ์‹œ์ž‘ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ณ  ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ
  2. ํ˜„์žฌ ๋…ธ๋“œ์—์„œ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ๋…ธ๋“œ๋ฅผ ํ™•์ธ
    • ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๊ฐ€ ์žˆ์œผ๋ฉด ํ•ด๋‹น ๋…ธ๋“œ๋กœ ์ด๋™
    • ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ผ๋ฉด ์Šคํ‚ต
  3. ๋” ์ด์ƒ ๋ฐฉ๋ฌธํ•  ๋…ธ๋“œ๊ฐ€ ์—†์œผ๋ฉด ์ด์ „ ๋…ธ๋“œ๋กœ ๋˜๋Œ์•„๊ฐ
  4. ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•  ๋•Œ๊นŒ์ง€ 2~3 ๊ณผ์ • ๋ฐ˜๋ณต

๐Ÿ”น DFS ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

DFS๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ์žฌ๊ท€(Recursive) ๋ฐฉ์‹
  2. ์Šคํƒ(Stack) ์‚ฌ์šฉ ๋ฐฉ์‹(๋ฐ˜๋ณต๋ฌธ)

๐ŸŸข 1. DFS ์žฌ๊ท€(Recursive) ๋ฐฉ์‹ ๊ตฌํ˜„ (Python)

def dfs_recursive(graph, node, visited):
    if node in visited:  # ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ๊ฒฝ์šฐ ์ข…๋ฃŒ
        return
    visited.add(node)  # ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ
    print(node, end=" ")  # ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ ์ถœ๋ ฅ

    for neighbor in graph[node]:  # ์ธ์ ‘ ๋…ธ๋“œ ํƒ์ƒ‰
        dfs_recursive(graph, neighbor, visited)

# ๊ทธ๋ž˜ํ”„ (์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ๋ฐฉ์‹)
graph = {
    1: [2, 3],
    2: [4, 5],
    3: [6, 7],
    4: [],
    5: [],
    6: [],
    7: []
}

visited_set = set()
dfs_recursive(graph, 1, visited_set)

์ถœ๋ ฅ:

1 2 4 5 3 6 7

๐Ÿ“Œ ์žฌ๊ท€ ๋ฐฉ์‹์€ ์Šคํƒ์„ ์ด์šฉํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•œ ์›๋ฆฌ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.


 

๐ŸŸข 2. DFS ์Šคํƒ(Stack) ์‚ฌ์šฉ ๋ฐฉ์‹ ๊ตฌํ˜„ (๋ฐ˜๋ณต๋ฌธ)

def dfs_stack(graph, start):
    visited = set()
    stack = [start]  # ์Šคํƒ ์ดˆ๊ธฐํ™”

    while stack:
        node = stack.pop()  # ์Šคํƒ์—์„œ ๋…ธ๋“œ ๊บผ๋‚ด๊ธฐ
        if node not in visited:
            visited.add(node)  # ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ
            print(node, end=" ")  

            # ์Šคํƒ์— ์ธ์ ‘ ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ (๋ฐ˜๋Œ€๋กœ ๋„ฃ์œผ๋ฉด ์ˆœ์„œ ์œ ์ง€)
            stack.extend(reversed(graph[node]))

# ๊ทธ๋ž˜ํ”„ (์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ๋ฐฉ์‹)
graph = {
    1: [2, 3],
    2: [4, 5],
    3: [6, 7],
    4: [],
    5: [],
    6: [],
    7: []
}

dfs_stack(graph, 1)

์ถœ๋ ฅ:

1 2 4 5 3 6 7

๐Ÿ“Œ ์Šคํƒ์„ ์‚ฌ์šฉํ•˜๋ฉด ์žฌ๊ท€ ์—†์ด DFS๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


 

๐Ÿ”น DFS vs BFS ์ฐจ์ด์ 

๋น„๊ต ํ•ญ๋ชฉ DFS(Depth-First Search) BFS(Breadth-First Search)
ํƒ์ƒ‰ ๋ฐฉ์‹ ์ตœ๋Œ€ํ•œ ๊นŠ์ด ํƒ์ƒ‰ ํ›„ ๋ฐฑํŠธ๋ž˜ํ‚น ํ˜„์žฌ ๋ ˆ๋ฒจ(๋„ˆ๋น„)์—์„œ ํƒ์ƒ‰ ํ›„ ๋‹ค์Œ ๋ ˆ๋ฒจ๋กœ ์ด๋™
์ž๋ฃŒ๊ตฌ์กฐ ์Šคํƒ (or ์žฌ๊ท€ ํ˜ธ์ถœ) ํ (Queue)
๊ฒฝ๋กœ ํƒ์ƒ‰ ๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์ ํ•ฉ ์ตœ๋‹จ ๊ฒฝ๋กœ(๊ฐ€์ค‘์น˜ ์—†๋Š” ๊ทธ๋ž˜ํ”„) ํƒ์ƒ‰์— ์ ํ•ฉ
๊ตฌํ˜„ ๋‚œ์ด๋„ ๋น„๊ต์  ๊ฐ„๋‹จ ์ƒ๋Œ€์ ์œผ๋กœ ๋ณต์žก
์‚ฌ์šฉ ์˜ˆ์‹œ ๋ฐฑํŠธ๋ž˜ํ‚น(๋ฏธ๋กœ ์ฐพ๊ธฐ, ํผ์ฆ ํ•ด๊ฒฐ, ์กฐํ•ฉ) ์ตœ๋‹จ ๊ฒฝ๋กœ ํƒ์ƒ‰ (๊ธธ ์ฐพ๊ธฐ, ๋„คํŠธ์›Œํฌ ํƒ์ƒ‰)


๐Ÿ”น DFS ์‘์šฉ ์‚ฌ๋ก€

  1. ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰
    • ์—ฐ๊ฒฐ ์š”์†Œ ์ฐพ๊ธฐ, ๊ฒฝ๋กœ ํƒ์ƒ‰
  2. ๋ฐฑํŠธ๋ž˜ํ‚น ๋ฌธ์ œ ํ•ด๊ฒฐ
    • ํผ์ฆ ๋ฌธ์ œ (์˜ˆ: N-Queen ๋ฌธ์ œ)
    • ์กฐํ•ฉ(combination)๊ณผ ์ˆœ์—ด(permutation)
  3. ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ ์—ฌ๋ถ€ ํ™•์ธ
    • ๋„คํŠธ์›Œํฌ ๊ทธ๋ž˜ํ”„์—์„œ ์—ฐ๊ฒฐ ์—ฌ๋ถ€ ๊ฒ€์‚ฌ
  4. ์‚ฌ์ดํด ๊ฒ€์ถœ
    • ๋ฐฉํ–ฅ/๋ฌด๋ฐฉํ–ฅ ๊ทธ๋ž˜ํ”„์—์„œ ์‚ฌ์ดํด ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ
  5. ๋ฏธ๋กœ ์ฐพ๊ธฐ (DFS ๊ธฐ๋ฐ˜ ๋ฐฑํŠธ๋ž˜ํ‚น)
    • ํ•œ ๊ฒฝ๋กœ๋ฅผ ๋๊นŒ์ง€ ํƒ์ƒ‰ํ•œ ํ›„ ๋‹ค๋ฅธ ๊ฒฝ๋กœ ํƒ์ƒ‰



๐Ÿ”น DFS ์‹œ๊ฐ„ ๋ณต์žก๋„ & ๊ณต๊ฐ„ ๋ณต์žก๋„

  • ์‹œ๊ฐ„ ๋ณต์žก๋„:
    • ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ: O(V + E) (์ •์  V, ๊ฐ„์„  E)
    • ์ธ์ ‘ ํ–‰๋ ฌ: O(V²)
  • ๊ณต๊ฐ„ ๋ณต์žก๋„:
    • O(V) (๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ ๋ฐฐ์—ด, ์Šคํƒ/์žฌ๊ท€ ํ˜ธ์ถœ ์Šคํƒ)


๐Ÿ”น ์ฝ”๋”ฉ ํ…Œ์ŠคํŠธ ๋ฌธ์ œ(๋ฐฑ์ค€ 2023)

1. ๋ฌธ์ œ ์„ค๋ช…

์ˆ˜๋นˆ์ด๊ฐ€ ์„ธ์ƒ์—์„œ ๊ฐ€์žฅ ์ข‹์•„ํ•˜๋Š” ๊ฒƒ์€ ์†Œ์ˆ˜์ด๊ณ , ์ทจ๋ฏธ๋Š” ์†Œ์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ๋…ธ๋Š” ๊ฒƒ์ด๋‹ค. ์š”์ฆ˜ ์ˆ˜๋นˆ์ด๊ฐ€ ๊ฐ€์žฅ ๊ด€์‹ฌ์žˆ์–ด ํ•˜๋Š” ์†Œ์ˆ˜๋Š” 7331์ด๋‹ค. 7331์€ ์†Œ์ˆ˜์ธ๋ฐ, ์‹ ๊ธฐํ•˜๊ฒŒ๋„ 733๋„ ์†Œ์ˆ˜์ด๊ณ , 73๋„ ์†Œ์ˆ˜์ด๊ณ , 7๋„ ์†Œ์ˆ˜์ด๋‹ค. ์ฆ‰, ์™ผ์ชฝ๋ถ€ํ„ฐ 1์ž๋ฆฌ, 2์ž๋ฆฌ, 3์ž๋ฆฌ, 4์ž๋ฆฌ ์ˆ˜ ๋ชจ๋‘ ์†Œ์ˆ˜์ด๋‹ค! ์ˆ˜๋นˆ์ด๋Š” ์ด๋Ÿฐ ์ˆซ์ž๋ฅผ ์‹ ๊ธฐํ•œ ์†Œ์ˆ˜๋ผ๊ณ  ์ด๋ฆ„ ๋ถ™์˜€๋‹ค.

์ˆ˜๋นˆ์ด๋Š” N์ž๋ฆฌ์˜ ์ˆซ์ž ์ค‘์—์„œ ์–ด๋–ค ์ˆ˜๋“ค์ด ์‹ ๊ธฐํ•œ ์†Œ์ˆ˜์ธ์ง€ ๊ถ๊ธˆํ•ด์กŒ๋‹ค. N์ด ์ฃผ์–ด์กŒ์„ ๋•Œ, ์ˆ˜๋นˆ์ด๋ฅผ ์œ„ํ•ด N์ž๋ฆฌ ์‹ ๊ธฐํ•œ ์†Œ์ˆ˜๋ฅผ ๋ชจ๋‘ ์ฐพ์•„๋ณด์ž.(https://www.acmicpc.net/problem/2023)

(์ œํ•œ ์‹œ๊ฐ„ 2์ดˆ, 1<= N <= 8)

2. ์ฒ˜์Œ์— ์‚ฌ์šฉํ•œ ๋ฐฉ๋ฒ•(C++ 17)

์ฒ˜์Œ์—๋Š” DFS๋ฌธ์ œ๋ผ๋Š” ๊ฒƒ์„ ๊นจ๋‹ซ์ง€ ๋ชปํ•˜๊ณ , std::string์„ ํ™œ์šฉํ•ด์„œ ๋ฌธ์ œ๋ฅผ ํ’€์—ˆ์Šต๋‹ˆ๋‹ค. ์ดˆ๊ธฐ ๋ฒ„์ „์€ ์ œํ•œ์‹œ๊ฐ„์„ ํ›Œ์ฉ ๋„˜๊ฒผ์œผ๋‚˜, 2์˜ ๋ฐฐ์ˆ˜๋Š” ์†Œ์ˆ˜๊ฐ€ ๋  ์ˆ˜ ์—†๋‹ค(2 ์ œ์™ธ) ๋ผ๋Š” ๊ทœ์น™์„ ๊นจ๋‹ซ๊ณ  ์ง์ˆ˜๋ฅผ ์ œ์™ธํ•˜์ž 1850ms ๋กœ ๊ฒจ์šฐ ํ†ต๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ N์ด ์กฐ๊ธˆ์ด๋ผ๋„ ๋Š˜์—ˆ์„ ๊ฒฝ์šฐ์—๋Š” ๋ณต์‚ฌ์—ฐ์‚ฐ๊ณผ ๋”๋ถˆ์–ด ์‹œ๊ฐ„์ด ๋งŽ์ด ์†Œ์š”๋˜๋Š” ์ข‹์ง€ ์•Š์€ ์ฝ”๋“œ์˜€์Šต๋‹ˆ๋‹ค. ์šฐ์„  ๋จผ์ € ์ฝ”๋“œ๋ฅผ ๋ณด์—ฌ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

// ๋ฐฑ์ค€ 2023
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cmath>
using namespace std;

bool isPrime(int num) {
    if (num <= 1) return false; // 1 ์ดํ•˜์˜ ์ˆซ์ž๋Š” ์†Œ์ˆ˜๊ฐ€ ์•„๋‹˜
    if (num <= 3) return true;  // 2์™€ 3์€ ์†Œ์ˆ˜
    if (num % 2 == 0 || num % 3 == 0) return false; // 2์™€ 3์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€๋ฉด ์†Œ์ˆ˜๊ฐ€ ์•„๋‹˜

    for (int i = 5; i * i <= num; i += 6) {
        if (num % i == 0 || num % (i + 2) == 0) return false;
    }
    return true;
}

int main()
{
    int N;
    cin >> N;

    int min = pow(10, N-1);
    int max = pow(10, N);
    for (int i = min; i < max; i++)
    {
        if (i > 10 && i % 2 == 0)
            continue;

        bool isPrimeNumber = true;
        string str = to_string(i);
        for (int j = 0; j < str.length(); j++)
        {
            string strNum;
            int idx = 0;
            while (idx <= j)
                strNum += str[idx++];

            int target = stoi(strNum);
            if (!isPrime(target))
            {
                isPrimeNumber = false;
                break;
            }
        }

        if (isPrimeNumber)
            cout << i << endl;
    }
}

 

3. DFS๋ฅผ ํ™œ์šฉํ•œ ์ตœ์ข… ๋ฐฉ๋ฒ•(C++ 17)

ํ—ˆ๋ฌดํ•˜๊ฒŒ๋„ DFS๋Š” 0ms๊ฐ€ ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค. ์ผ์˜ ์ž๋ฆฌ์—์„œ ์†Œ์ˆ˜๋Š” 2, 3, 5, 7 ๋ฟ์ด๊ณ  ๊ทธ ์ดํ›„์— ์˜ฌ ์ˆ˜ ์žˆ๋Š” ์ˆ˜๋Š” 5๊ฐœ(ํ™€์ˆ˜) ๋ฟ์ž…๋‹ˆ๋‹ค. 2 -> 23, 23-> 233 -> 2337 ์ฒ˜๋Ÿผ ๊นŠ์ด ์šฐ์„  ๋ฐฉ์‹์œผ๋กœ ์„œ์น˜ํ•ด๋‚˜๊ฐ€๋Š” DFS๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ํ’€ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ๋ณด๊ณ  DFS๋ฅผ ํ™œ์šฉํ•ด์•ผ๊ฒ ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ค‘์š”ํ•˜๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// ๋ฐฑ์ค€ 2023
#include <iostream>
#include <vector>
using namespace std;
int N;

bool isPrime(int num) {
    if (num <= 1) return false; // 1 ์ดํ•˜์˜ ์ˆซ์ž๋Š” ์†Œ์ˆ˜๊ฐ€ ์•„๋‹˜
    if (num <= 3) return true;  // 2์™€ 3์€ ์†Œ์ˆ˜
    if (num % 2 == 0 || num % 3 == 0) return false; // 2์™€ 3์œผ๋กœ ๋‚˜๋ˆ„์–ด ๋–จ์–ด์ง€๋ฉด ์†Œ์ˆ˜๊ฐ€ ์•„๋‹˜

    for (int i = 5; i * i <= num; i += 6) {
        if (num % i == 0 || num % (i + 2) == 0) return false;
    }
    return true;
}

void DFS(int num, int digit)
{
    if (digit == N)
    {
        if (isPrime(num))
        {
            cout << num << endl;
            return;
        }
    }

    for (int i = 1; i < 10; i += 2)
    {
        int next = num * 10 + i;
        if (isPrime(next))
            DFS(next, digit + 1);
    }
}

int main()
{
    cin >> N;
    DFS(2, 1);
    DFS(3, 1);
    DFS(5, 1);
    DFS(7, 1);
}

 


๐Ÿ”น ์ •๋ฆฌ

  • DFS๋Š” ์Šคํƒ(LIFO) ๊ตฌ์กฐ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๊ทธ๋ž˜ํ”„๋ฅผ ๊นŠ์ด ํƒ์ƒ‰ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜
  • ์žฌ๊ท€(Recursive) ๋ฐฉ์‹๊ณผ ์Šคํƒ(Stack) ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ ๊ฐ€๋Šฅ
  • ๋ฐฑํŠธ๋ž˜ํ‚น, ๋ฏธ๋กœ ํƒ์ƒ‰, ๊ฒฝ๋กœ ํƒ์ƒ‰ ๋“ฑ ๋‹ค์–‘ํ•œ ๋ฌธ์ œ ํ•ด๊ฒฐ์— ์‚ฌ์šฉ
  • BFS์™€ ๋น„๊ตํ•˜๋ฉด ์ตœ๋‹จ ๊ฒฝ๋กœ ํƒ์ƒ‰๋ณด๋‹ค๋Š” ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ํƒ์ƒ‰ํ•  ๋•Œ ์œ ๋ฆฌํ•จ

DFS๊ฐ€ ํ•„์š”ํ•œ ์ƒํ™ฉ์ด๋ผ๋ฉด, ์žฌ๊ท€ ๋ฐฉ์‹๊ณผ ์Šคํƒ ๋ฐฉ์‹ ์ค‘ ์ ์ ˆํ•œ ๋ฐฉ๋ฒ•์„ ์„ ํƒํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๐Ÿš€

 

๋Œ“๊ธ€