BFS (Breadth First Search)

2023. 5. 5. 10:57·알고리즘 (with JAVA)/기본 알고리즘

1. 개념 설명

(1) BFS는 너비 우선 탐색으로 최대한 깊숙이 들어가서 탐색을 시작하는 DFS와는 달리 인접한 노드부터 먼저

탐색하는 방법이다.

( 아래 2. 과정을 통해 이해하자. )

 

(2) BFS는 재귀호출을 사용하는 DFS와는 달리, 자료구조 큐(Queue)를 사용하는 경우가 일반적이다.

( 그러므로, 3. 코드에서는 큐를 이용한 BFS를 보여줄 것이다. )

 

 

 

 

2. 과정

- 실제로 수행되는 과정이며, 앞서 DFS(깊이 우선 탐색)과 BFS(너비 우선 탐색)을 비교하고 있다.

 

 

 

 

3. 코드

: BFS는 재귀를 사용하지 않고 일반적으로 큐를 통해 구현한다.

Graph

( 아래의 코드 (1)과 (2)는 위 그래프 그림을 기반으로 코드를 작성했다. )

 

(1) 인접 행렬

public class BFS_Matrix {
   static Queue<Integer> q = new LinkedList<>();
   static boolean[] visited = new boolean[9]; // 0을 제외한 그래프에서 1~8 중에 방문 했는지 체크하는 변수
   static int[][] graph = {
            {},
            {0, 0, 1, 1, 0, 0, 0, 0, 1},
            {0, 1, 0, 0, 0, 0, 1, 0, 1},
            {0, 1, 0, 0, 0, 1, 0, 0, 0},
            {0, 0, 0, 0, 0, 1, 0, 1, 0},
            {0, 0, 0, 1, 1, 0, 0, 1, 0},
            {0, 0, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 1, 1, 0, 0, 0},
            {0, 1, 1, 0, 0, 0, 0, 0, 0}
    };    // 인접 행렬 그래프이며, 0행과 0열은 모두 0으로 비어두었다.
    
    public static void main(String[] args) {
        // 시작 지점은 1로 가정한다.
        bfs(1);
    }
    
   static void bfs(int nodeIndex) {
        // 시작 노드 또는 해당 인덱스 노드를 방문 처리
        q.add(nodeIndex);
        visited[nodeIndex] = true;
        
        while(!q.isEmpty()) {
            nodeIndex = q.poll();
            // 방문 노드 출력
            System.out.print(nodeIndex + " -> ");
            
            for(int i=1; i<=8; i++) {
                if(graph[nodeIndex][i] == 1 && !visited[i]) {
                    q.add(i);
                    visited[i] = true;
                }
            }
        }
    }
}
Colored by Color Scripter
cs

 

(2) 인접 리스트

public class BFS_List {
   static Queue<Integer> q = new LinkedList<>();
   static boolean[] visited = new boolean[9]; // 0을 제외한 그래프에서 1~8 중에 방문 했는지 체크하는 변수
   static int[][] graph = { {}, {2,3,8}, {1,6,8}, {1,5}, {5,7}, {3,4,7}, {2}, {4,5}, {1,2}}; // 0을 제외한 해당 인덱스 노드의 인접한 노드 리스트
    
    public static void main(String[] args) {
        // 시작 지점은 1로 가정한다.
        bfs(1);
    }
    
   static void bfs(int nodeIndex) {
        // 시작 노드 또는 해당 인덱스 노드를 방문 처리
        q.add(nodeIndex);
        visited[nodeIndex] = true;
        
        while(!q.isEmpty()) {
            nodeIndex = q.poll();
            System.out.print(nodeIndex + " -> ");
            
            for(int i=0; i< graph[nodeIndex].length; i++) {
                int node = graph[nodeIndex][i];
                if(!visited[node]) {
                    q.add(node);
                    visited[node] = true;
                }
            }
        }
    }
}
Colored by Color Scripter
cs

 

 

 

4. 시간 복잡도

(1) 인접 행렬: O(V^2)

(2) 인접 리스트: O(V+E)

( 이때, V는 정점, E는 간선을 의미한다. )

 

 

 

 

5. 장점

(1) 만약 여러 갈래 중 무한한 길이를 가지는 경로가 존재하고 탐색 목표가 다른 경로에 존재한다면, DFS의 경우

계속 무한한 길이의 경로에서 영원히 종료하지 못하지만 BFS는 모든 경로를 동시에 진행되기 떄문에 탐색이

가능하다.

 

(2) BFS는 가중치가 모두 똑같은 그래프에서 시작점과 끝점이 주어진다면, 최단 경로를 알아낼 수 있다.

 

 

 

6. 단점

(1) 경로가 매우 길 경우에는 탐색 가지가 급격히 증가함에 따라 보다 많은 기억 공간을 필요로 하게 된다.

 

(2) 해가 존재하지 않은 유한 그래프인 경우 모든 그래프를 탐색한 후에서야 실패로 끝난다.

 

 

 

 

7. 관련 문제 풀어보기

1260번: DFS와 BFS (acmicpc.net)

 

-> 풀이는 아래의 링크로 가면 된다.

 

1260번: DFS & BFS (실버 2) (tistory.com)

 

 

 

 

8. 참고 사이트

DFS & BFS | 👨🏻‍💻 Tech Interview (gyoogle.dev)

저작자표시 (새창열림)

'알고리즘 (with JAVA) > 기본 알고리즘' 카테고리의 다른 글

다익스트라 (Dijkstra)  (0) 2023.05.05
DFS (Depth First Search)  (0) 2023.05.05
해시 테이블 (Hash Table)  (0) 2023.05.01
이진 탐색 (Binary Search)  (0) 2023.04.29
계수 정렬 (Counting Sort)  (0) 2023.04.29
'알고리즘 (with JAVA)/기본 알고리즘' 카테고리의 다른 글
  • 다익스트라 (Dijkstra)
  • DFS (Depth First Search)
  • 해시 테이블 (Hash Table)
  • 이진 탐색 (Binary Search)
백_곰
백_곰
  • 백_곰
    친절한 코딩
    백_곰
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 알고리즘 (with JAVA)
        • 기본 알고리즘
        • 완전 탐색
        • 분할 정복 알고리즘
        • 동적 계획법
        • 탐욕법
        • 코딩 테스트 기출 문제
        • 코드트리 조별과제
      • 백준 (with JAVA)
        • 완전 탐색
        • 분할 정복
        • 그 외
      • 자바
        • 개발 환경 구축하기
        • 팁
        • 기본적인 개념
        • 컬렉션 프레임워크
        • 프로세스와 쓰레드
        • 지네릭스
        • 람다식
        • 스트림
        • 입출력 IO
        • 네트워킹
        • 열거형(enums)
        • java.lang 패키지
        • java.time 패키지
        • 유용한 클래스들
        • 형식화 클래스들
      • 안드로이드 with 자바
        • 응용 문제들
        • 자잘한 문제들
        • 오류 보고서
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      중간연산
      다형성
      유용한 클래스
      map()
      선택 정렬
      알고스팟
      Arrays
      문자 기반 스트림
      안드로이드 스튜디오
      Collections Framework
      코드트리
      java.lang패키지
      역직렬화
      outputstream
      제자리 정렬
      람다식
      snail
      소켓 프로그래밍
      자바 개념
      불안정 정렬
      코딩테스트
      serializable
      스트림
      ServerSocket
      InputStream
      안정 정렬
      코딩트리조별과제
      file
      java.time 패키지
      TCP 소켓 프로그래밍
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    백_곰
    BFS (Breadth First Search)
    상단으로

    티스토리툴바