๐Ÿ“š DFS / BFS

๐Ÿ“š DFS / BFS


๐Ÿ“š DFS ์™€ BFS

  • DFS = Depth Frist Search = ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰
  • BFS = Breadth First Search = ๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰

๊ทธ๋ž˜ํ”„๋‚˜ ํŠธ๋ฆฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํƒ์ƒ‰ํ•˜๊ฑฐ๋‚˜ ์ˆœํšŒํ•˜๋Š” ๊ธฐ๋ณธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.


๐Ÿ“š DFS๋ž€?

  • ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰
  • ์‹œ๊ฐ„ ๋ณต์žก๋„ : (O(V+E))
  • ๊ณต๊ฐ„ ๋ณต์žก๋„ : (O(H)) (H : ํŠธ๋ฆฌ ๋†’์ด)
  • ํ•˜๋‚˜์˜ ๊ฒฝ๋กœ๋ฅผ ๋๊นŒ์ง€ ํƒ์ƒ‰ํ•œ ๋’ค์—์•ผ ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋กœ ์ด๋™
  • ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์€ ์Šคํƒ, ์žฌ๊ท€ ํ˜ธ์ถœ์€ ์Šคํƒ์„ ์•”๋ฌต์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์—, DFS๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์žฌ๊ท€๋กœ ๊ตฌํ˜„ ๋˜๊ธฐ๋„ ํ•œ๋‹ค.

๐Ÿ”Ž DFS ํŠน์ง•

  • ํƒ์ƒ‰ ๋ฐฉ์‹ : ๋…ธ๋“œ ๋ฐฉ๋ฌธ > ๋‹ค์Œ ๊นŠ์€ ๋…ธ๋“œ ๋ฐฉ๋ฌธ > ๋” ์ด์ƒ ๋ฐฉ๋ฌธํ•  ๋…ธ๋“œ๊ฐ€ ์—†์œผ๋ฉด ์ด์ „ ๋…ธ๋“œ๋กœ ๋ฐฑํŠธ๋ž˜ํ‚น
  • ๊ตฌํ˜„ : ์žฌ๊ท€ ๋˜๋Š” ๋ช…์‹œ์ ์ธ ์Šคํƒ ์‚ฌ์šฉ

๐Ÿ’ป DFS ๊ตฌํ˜„

#include <iostream>
#include <vector>
using namespace std;

void dfs(int node, vector<bool>& visited, vector<vector<int>>& graph) {
    visited[node] = true;  // ํ˜„์žฌ ๋…ธ๋“œ ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ
    cout << node << " ";  // ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ ์ถœ๋ ฅ

    for (int neighbor : graph[node]) {  // ํ˜„์žฌ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋ชจ๋“  ์ด์›ƒ ๋…ธ๋“œ ํƒ์ƒ‰
        if (!visited[neighbor]) {       // ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๋ผ๋ฉด ์žฌ๊ท€ ํ˜ธ์ถœ
            dfs(neighbor, visited, graph);
        }
    }
}

int main() {
    // ๊ทธ๋ž˜ํ”„ ์ž…๋ ฅ (์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ๋ฐฉ์‹)
    vector<vector<int>> graph = {
        {},        // 0๋ฒˆ ๋…ธ๋“œ (์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ)
        {2, 3},    // 1๋ฒˆ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋“ค
        {1, 4, 5}, // 2๋ฒˆ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋“ค
        {1},       // 3๋ฒˆ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋“ค
        {2},       // 4๋ฒˆ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋“ค
        {2}        // 5๋ฒˆ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋“ค
    };
    vector<bool> visited(6, false);  // ๋ฐฉ๋ฌธ ์—ฌ๋ถ€ ๋ฐฐ์—ด

    cout << "DFS Traversal: ";
    dfs(1, visited, graph);  // 1๋ฒˆ ๋…ธ๋“œ๋ถ€ํ„ฐ ํƒ์ƒ‰ ์‹œ์ž‘
    return 0;
}

๐Ÿ’ป ํŠธ๋ฆฌ์˜ ์ˆœํšŒ ๋ฐฉ๋ฒ•

  1. ์ „์œ„ ์ˆœํšŒ(Preorder Traversal)
    • ํ˜„์žฌ ๋…ธ๋“œ > ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ > ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ
void preorder(Treenode* node, vector<int>& res) {
    if(!node)
    {
        return;
    }
    res.push_back(node->val); // ํ˜„์žฌ ๋…ธ๋“œ ์ฒ˜๋ฆฌ(์ˆœ์„œ๋ฅผ ์ถœ๋ ฅํ•  res)
    preorder(node->left, res); // ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ํƒ์ƒ‰
    preorder(node->right, res); // ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ํƒ์ƒ‰
}
  1. ์ค‘์œ„ ์ˆœํšŒ(Inorder Traversal)
    • ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ > ํ˜„์žฌ ๋…ธ๋“œ > ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ
void inorder(TreeNode* node, vector<int>& res) {
    if(!node)
    {
        return;
    }
    inorder(node->left, res);
    res.push_back(node->val);
    inorder(node->right, res);
}
  1. ํ›„์œ„ ์ˆœํšŒ(Postorder Traversal)
    • ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ > ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ > ํ˜„์žฌ ๋…ธ๋“œ
void postorder(Treenode* node, vector<int>& res) {
    if(!node)
    {
        return;
    }
    postorder(node->left, res);
    postorder(node->right, res);
    res.push_back(node->val);
}

๐Ÿ“š BFS

  • ๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰
  • ์‹œ๊ฐ„ ๋ณต์žก๋„ : (O(V+E))
  • ๊ณต๊ฐ„ ๋ณต์žก๋„ : (O(V))
  • ํ•œ ๋…ธ๋“œ์˜ ๋ชจ๋“  ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋ฅผ ๋จผ์ € ๋ฐฉ๋ฌธํ•œ ๋’ค, ๊ทธ ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ๋„˜์–ด๊ฐ„๋‹ค.
  • ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์€ ํ ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๐Ÿ”Ž BFS ํŠน์ง•

  • ํƒ์ƒ‰ ๋ฐฉ์‹ : ํ˜„์žฌ ๋ ˆ๋ฒจ์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•œ ํ›„, ๋‹ค์Œ ๋ ˆ๋ฒจ์˜ ๋…ธ๋“œ๋กœ ๋„˜์–ด๊ฐ
  • ๊ตฌํ˜„ : ๋ช…์‹œ์ ์ธ ํ(queue) ์‚ฌ์šฉ

๐Ÿ’ป BFS ๊ตฌํ˜„

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

void bfs(int start, vector<vector<int>>& graph) {
    vector<bool> visited(graph.size(), false); // ๋ฐฉ๋ฌธ ์—ฌ๋ถ€ ๋ฐฐ์—ด
    queue<int> q;  // ํƒ์ƒ‰์„ ์œ„ํ•œ ํ

    q.push(start);  // ์‹œ์ž‘ ๋…ธ๋“œ๋ฅผ ํ์— ์ถ”๊ฐ€
    visited[start] = true;  // ์‹œ์ž‘ ๋…ธ๋“œ ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ

    while (!q.empty()) {
        int node = q.front();  // ํ์˜ ์ฒซ ๋ฒˆ์งธ ๋…ธ๋“œ๋ฅผ ๊ฐ€์ ธ์˜ด
        q.pop();               // ํ์—์„œ ์ œ๊ฑฐ
        cout << node << " ";   // ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ ์ถœ๋ ฅ

        for (int neighbor : graph[node]) {  // ํ˜„์žฌ ๋…ธ๋“œ์˜ ๋ชจ๋“  ์ธ์ ‘ ๋…ธ๋“œ ํƒ์ƒ‰
            if (!visited[neighbor]) {       // ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๋ผ๋ฉด
                q.push(neighbor);           // ํ์— ์ถ”๊ฐ€
                visited[neighbor] = true;   // ๋ฐฉ๋ฌธ ์ฒ˜๋ฆฌ
            }
        }
    }
}

int main() {
    // ๊ทธ๋ž˜ํ”„ ์ž…๋ ฅ (์ธ์ ‘ ๋ฆฌ์ŠคํŠธ ๋ฐฉ์‹)
    vector<vector<int>> graph = {
        {},        // 0๋ฒˆ ๋…ธ๋“œ (์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ)
        {2, 3},    // 1๋ฒˆ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋“ค
        {1, 4, 5}, // 2๋ฒˆ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋“ค
        {1},       // 3๋ฒˆ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋“ค
        {2},       // 4๋ฒˆ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋“ค
        {2}        // 5๋ฒˆ ๋…ธ๋“œ์™€ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋“ค
    };

    cout << "BFS Traversal: ";
    bfs(1, graph);  // 1๋ฒˆ ๋…ธ๋“œ๋ถ€ํ„ฐ ํƒ์ƒ‰ ์‹œ์ž‘
    return 0;
}