๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ Algorithm/์•Œ๊ณ ๋ฆฌ์ฆ˜-Python

[์•Œ๊ณ ๋ฆฌ์ฆ˜] Day3 - 1260๋ฒˆ DFS์™€ BFS

by Danna 2018. 8. 8.
728x90
728x90

00 ๋ฌธ์ œ


01 DFS ์•Œ๊ณ ๋ฆฌ์ฆ˜?
  • Depth First Search, ๊นŠ์ด ์šฐ์„  ํƒ์ƒ‰์ด๋ผ๋Š” ๋œป.
  • ํ•˜๋‚˜์˜ ๋…ธ๋“œ์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ๋งˆ์ง€๋ง‰ ์ง€์ ๊นŒ์ง€ ๊ณ„์† ํƒ์ƒ‰ํ•˜๋Š” ํ–‰๋™์„ ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜
  • ์ฆ‰, ์‹œ์ž‘์ ์„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ€์žฅ ์•„๋ž˜๊นŒ์ง€ ์ด๋™ํ•˜๋ฉด์„œ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ์‹ -> ์Šคํƒ์„ ์ด์šฉํ•˜์—ฌ ํ‘ธ๋Š” ๋ฐฉ์‹
  • ์Šคํƒ์— ๊ฐ’์„ ๋„ฃ์–ด์ฃผ๊ณ , ๊ทธ ๊ฐ’์„ ํ†ตํ•ด ํ™•์ธํ•˜๋ฉฐ ์ข…๋ฃŒ ์กฐ๊ฑด์€ ์Šคํƒ์ด ๋น„์–ด์žˆ์„ ๋•Œ์ด๋‹ค.
  • DFS์˜ ์žฅ์ ์€ ๊นŠ์€ ๊ณณ์— ์žˆ์„์ˆ˜๋ก ๋นจ๋ฆฌ ์ฐพ์•„๋‚ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ 
  • ๋‹จ์ ์€ ์ž์นซํ•˜๋ฉด overflow๊ฐ€ ๋‚  ์ˆ˜๋„ ์žˆ๊ณ , ์–ป์–ด์ง„ ํ•ด๊ฐ€ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ผ๋Š” ๋ณด์žฅ์ด ์—†๋‹ค.

02 DFS ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„ ๋ฐฉ์‹
  • ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋“ค์„ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด NxN ํฌ๊ธฐ์˜ adj_mat ๋ฐฐ์—ด๊ณผ ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด Nx1 ํฌ๊ธฐ์˜ visited ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•œ๋‹ค. 
  • add_matrix ํ•จ์ˆ˜์—์„œ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋ฅผ ์ž…๋ ฅ๋ฐ›๊ณ , ํ•ด๋‹น ๊ฐ’์„ 1๋กœ ์„ค์ •ํ•œ๋‹ค.
  • Stack์„ ์ด์šฉํ•ด DFS๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
- ํ˜„์žฌ ๊ธฐ์ค€์ ์ด ๋˜๋Š” ์ •์ ์„ row ๋ณ€์ˆ˜์— ์ €์žฅํ•œ๋‹ค. 
- ๋ฐ˜๋ณต์„ ์œ„ํ•ด i ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•œ๋‹ค. push ๋˜๋Š” pop ํ•  ๋•Œ ์ดˆ๊ธฐํ™”๋œ๋‹ค.
- row ์™€ i ๋…ธ๋“œ๊ฐ€ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๊ณ  i ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์•˜์„ ๊ฒฝ์šฐ push
- i ๋ณ€์ˆ˜๊ฐ€ N๊ณผ ๊ฐ™์•„์ง€๋ฉด ์ง€๋‚˜๊ฐˆ ๋…ธ๋“œ๊ฐ€ ์—†๋‹ค๋Š” ๋œป์ด๋ฏ€๋กœ pop
- ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ popํ•ด์„œ stack์ด ๋น„์–ด์žˆ์œผ๋ฉด ์ข…๋ฃŒํ•œ๋‹ค.

bool *adj_mat, *visited;

N += 1;        // ์ •์ ์˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค.

adj_mat = (bool *)calloc(N*N, sizeof(bool));
visited = (bool *)calloc(N, sizeof(bool));

void add_matrix(int N, int M)
{
        int i;
        int v1, v2;
        // input
        for (i = 0; i < M; i++)
        {
               scanf_s("%d %d", &v1, &v2);
               adj_mat[v1*N + v2] = 1;
               adj_mat[v2*N + v1] = 1;
        }
}

void depth_first_search(int N, int V)
{
        int i = 0;
        int row = V;
        printf("%d ", push(V));
        
        while (is_empty())
        {
               visited[row] = 1;
               if (adj_mat[row*N + i] == 1 && !visited[i])
               {
                       printf("%d ", push(i));
                       row = i;
                       i = 0;
               }
               if (i == N)
               {
                       pop(); 
                       row = top();
                       i = 0;
               }
               i++;
        }
}


03 BFS ์•Œ๊ณ ๋ฆฌ์ฆ˜?
  • Breadth First Search, ๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰์ด๋ผ๋Š” ๋œป.
  • ์‹œ์ž‘์ ์„ ๊ธฐ์ค€์œผ๋กœ DFS์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ฐ€์žฅ ์•„๋ž˜๊นŒ์ง€ ์ด๋™ํ•˜๋ฉด์„œ ํƒ์ƒ‰ -> ํ๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฐฉ์‹
  • BFS๋Š” ๊นŠ์ด ํƒ์ƒ‰๊ณผ ๋‹ค๋ฅด๊ฒŒ ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ ๋ฐฉ๋ฌธํ•œ๋‹ค.
  • ํ์— ๊ฐ’์„ ๋„ฃ์–ด์ฃผ๊ณ , ๊ทธ ๊ฐ’์„ ํ†ตํ•ด ํ™•์ธํ•˜๋ฉฐ ์ข…๋ฃŒ ์กฐ๊ฑด์€ ํ๊ฐ€ ๋น„์–ด์žˆ์„ ๋•Œ์ด๋‹ค.

04 BFS ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ตฌํ˜„ ๋ฐฉ์‹
  • ์ธ์ ‘ํ•œ ๋…ธ๋“œ๋“ค์„ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด NxN ํฌ๊ธฐ์˜ adj_mat ๋ฐฐ์—ด๊ณผ ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•ด Nx1 ํฌ๊ธฐ์˜ visited ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•œ๋‹ค. 
  • add_matrix ํ•จ์ˆ˜์—์„œ ์—ฐ๊ฒฐ๋œ ๋…ธ๋“œ๋ฅผ ์ž…๋ ฅ๋ฐ›๊ณ , ํ•ด๋‹น ๊ฐ’์„ 1๋กœ ์„ค์ •ํ•œ๋‹ค.
  • Queue๋ฅผ ์ด์šฉํ•ด BFS๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
    1) queue์˜ ๊ฐ€์žฅ ์•ž์— ์žˆ๋Š” ๋…ธ๋“œ๋ฅผ get
    2) ํ˜„์žฌ ๋…ธ๋“œ์— ์ธ์ ‘ํ•œ ๋ชจ๋“œ ๋…ธ๋“œ๋“ค ์ค‘ ์•„์ง ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๋“ค์„ queue์— put
    3) queue๊ฐ€ ๋น„์–ด์žˆ์ง€ ์•Š์œผ๋ฉด 1)๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹คํ–‰

void breath_first_search(int N, int V)
{
        int i = 0;
        int row = V - 1;
        printf("%d ", put(V));
        while (is_empty())
        {
               visited[row] = 1;
               
               get();  
                       
               for (i = 0; i < N; ++i)
               {
                       if (adj_mat[row*N + i] == 1 && !visited[i])
                       {
                              printf("%d ", put(i));
                              visited[i] = 1;
                       }
               }
               row = top();
        }
}


05 ์ „์ฒด ์†Œ์Šค ์ฝ”๋“œ

#include "stdafx.h"
#include "data_structure.h"
void add_matrix(int N, int M);
void print_matrix(bool* matrix, int N);
void depth_first_search(int N, int V);
void breath_first_search(int N, int V);
bool *adj_mat, *visited;
int main()
{
        int i, N, M, V;
        scanf_s("%d %d %d", &N, &M, &V);
        N += 1;        // ์ •์ ์˜ ๋ฒˆํ˜ธ๋Š” 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค.
        adj_mat = (bool *)calloc(N*N, sizeof(bool));
        visited = (bool *)calloc(N, sizeof(bool));
        init_node();
        add_matrix(N, M);
        //print_matrix(adj_mat, N);
        printf("- - - - - - - \n");
        depth_first_search(N, V);
        
        clear_node();
        for (i = 0; i < N; ++i)
               visited[i] = 0;
        printf("\n");
        breath_first_search(N, V);
        printf("\n");
        // finish
        free(adj_mat);
        free(visited);
    return 0;
}
void add_matrix(int N, int M)
{
        int i;
        int v1, v2;
        // input
        for (i = 0; i < M; i++)
        {
               scanf_s("%d %d", &v1, &v2);
               adj_mat[v1*N + v2] = 1;
               adj_mat[v2*N + v1] = 1;
        }
}
void print_matrix(bool* matrix, int N)
{
        int i, j;
        // print
        for (i = 0; i < N; ++i)
        {
               printf("row %d = ", i);
               for (j = 0; j < N; ++j)
               {
                       printf("%d ", matrix[i*N + j]);
               }
               printf("\n");
        }
}
void depth_first_search(int N, int V)
{
        int i = 0;
        int row = V;
        printf("%d ", push(V));
        
        while (is_empty())
        {
               visited[row] = 1;
               if (adj_mat[row*N + i] == 1 && !visited[i])
               {
                       printf("%d ", push(i)); 
                       row = i;
                       i = 0;
               }
               if (i == N)
               {
                       pop();  
                       row = top();
                       i = 0;
               }
               i++;
        }
}
void breath_first_search(int N, int V)
{
        int i = 0;
        int row = V;
        printf("%d ", put(V)); 
        while (is_empty())
        {
               visited[row] = 1;
               if (top() == row)
                       get();  
                       
               for (i = 0; i < N; ++i)
               {
                       if (adj_mat[row*N + i] == 1 && !visited[i])
                       {
                              printf("%d ", put(i)); 
                              visited[i] = 1;
                       }
               }
               row = top();
        }
}


06 data_structer header

#include <stdlib.h>
typedef struct _dnode {
        int key;
        struct _dnode *prev;
        struct _dnode *next;
}dnode;
dnode *head, *tail;
void init_node()
{
        head = (dnode *)calloc(1, sizeof(dnode));
        tail = (dnode *)calloc(1, sizeof(dnode));
        head->prev = head;
        head->next = tail;
        tail->prev = head;
        tail->next = tail;
}
/* * * * * * * * * * * * *
**      Stack push and pop * *
** * * * * * * * * * * * */
int push(int k)
{
        dnode *t;
        if ((t = (dnode *)malloc(sizeof(dnode))) == NULL)
        {
               printf("Out of memory !\n");
               return -1;
        }
        t->key = k;
        head->next->prev = t;
        t->next = head->next;
        t->prev = head;
        head->next = t;
        return k;
}
int pop()
{
        dnode *t;
        int k;
        if (head->next == tail)
        {
               printf("Stack underflow !\n");
               return -1;
        }
        t = head->next;
        k = t->key;
        head->next = t->next;
        t->next->prev = head;
        free(t);
        return k;
}
/* * * * * * * * * * * * *
**      Queue put and get  * *
** * * * * * * * * * * * */
int put(int k)
{
        dnode *t;
        if ((t = (dnode*)malloc(sizeof(dnode))) == NULL)
        {
               printf("Out of memory !! \n");
               return -1;
        }
        t->key = k;
        tail->prev->next = t;
        t->prev = tail->prev;
        tail->prev = t;
        t->next = tail;
        return k;
}
int get()
{
        dnode *t;
        int k;
        t = head->next;
        if (t == tail)
        {
               printf("Queue undeflow !! \n");
               return -1;
        }
        k = t->key;
        head->next = t->next;
        t->next->prev = head;
        free(t);
        return k;
}
void clear_node()
{
        dnode *t, *s;
        t = head->next;
        while (t != tail)
        {
               s = t;
               t = t->next;
               free(s);
        }
        head->next = tail;
        tail->prev = head;
}
void print_node()
{
        dnode *t;
        t = head->next;
        while (t != tail)
        {
               printf("%-6d", t->key);
               t = t->next;
        }
}
int is_empty()
{
        if (head->next == tail)
        {
               //printf("Linked list is empty !\n");
               return 0;
        }
        return 1;
}
int top()
{
        dnode *t;
        t = head->next;
        if (t == tail)
               return -1;
        return t->key;
}
int bottom()
{
        dnode *t;
        t = tail->prev;
        if (t == head)
               return -1;
        return t->key;
}
int is_in_stack(int k)
{
        dnode *t;
        t = head->next;
        while (t != tail)
        {
               if (t->key == k)
                       return 1;
               t = t->next;
        }
        return 0;
}


99 ์ฐธ๊ณ ์ž๋ฃŒ



728x90
728x90