티스토리 뷰

1. 그래프 + 스택을 이용한 DFS & BFS

package StudyJava.DFSBFS;

import java.util.LinkedList;
import java.util.NoSuchElementException;
import java.util.Stack;

class Queue<T> { ... } // 생략

class Graph {
    class Node { // 그래프 노드 :D
        int data;
        LinkedList<Node> adjacent;
        boolean marked;
        Node (int data) { // 생성자
            this.data = data;
            this.marked = false;
            adjacent = new LinkedList<Node>();
        }
    }
    Node[] nodes;
    Graph(int size) { // 생성자
        nodes = new Node[size];
        for(int i = 0; i < size; i++) {
            nodes[i] = new Node(i);
        }
    }
    void addEdge(int i1, int i2) { // 노드 연결
        Node n1 = nodes[i1];
        Node n2 = nodes[i2];
        if(!n1.adjacent.contains(n2)) { // n1노드와 n2노드가 연결되어 있지 않다면
            n1.adjacent.add(n2); // 연결 추가
        }
        if(!n2.adjacent.contains(n1)) {
            n2.adjacent.addFirst(n1);
        }
    }
    void dfs() {
        dfs(0);
    }
    void dfs(int index) {
        Node root = nodes[index];
        Stack<Node> stack = new Stack<>();
        stack.push(root);
        root.marked = true;
        while(!stack.isEmpty()) {
            Node r = stack.pop();
            for(Node n : r.adjacent) {
                if(n.marked == false) {
                    n.marked = true;
                    stack.push(n);
                }
            }
            visit(r);
        }
    }
    void bfs() {
        bfs(0);
    }
    void bfs(int index) {
        Node root = nodes[index];
        Queue<Node> queue = new Queue<>();
        queue.add(root);
        root.marked = true;
        while(!queue.isEmpty()) {
            Node r = queue.remove();
            for(Node n : r.adjacent) {
                if(n.marked == false) {
                    n.marked = true;
                    queue.add(n);
                }
            }
            visit(r);
        }
    }
    void visit(Node r) {
        System.out.print(r.data + " ");
    }
    
    void dfsR(Node r) { // 재귀함수를 이용한 dfs (=스택)
        if(r == null) return;
        r.marked = true;
        visit(r);
        for(Node n : r.adjacent) {
            if(n.marked == false) {
                dfsR(n);
            }
        }
    }
    void dfsR(int index) {
        Node r = nodes[index];
        dfsR(r);
    }
    void dfsR() {
        dfsR(0);
    }
}

public class MainClass {
    public static void main(String[] args) {
        Graph g = new Graph(9);
        g.addEdge(0, 1);
        g.addEdge(1, 2);
        g.addEdge(1, 3);
        g.addEdge(2, 3);
        g.addEdge(2, 4);
        g.addEdge(3, 4);
        g.addEdge(3, 5);
        g.addEdge(5, 6);
        g.addEdge(5, 7);
        g.addEdge(6, 8);
        g.dfsR();
    }
}

 

2. 인접행렬을 이용한 DFS BFS (백준 1260번)

package CodingTestMemory.BJ.BFSDFS.P1260;

import java.io.*;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
import java.util.StringTokenizer;

public class P1260 {
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static boolean[] visited;
    static int[][] graph;

    public static void bfs(int idx) throws IOException {
        Queue<Integer> queue = new LinkedList<>();
        queue.add(idx);
        visited[idx] = true;
        while(!queue.isEmpty()) {
            int e = queue.remove();
            bw.write(String.valueOf(e) + " ");
            for(int i = 1; i < visited.length; i++) {
                if(!visited[i] && graph[e][i] != 0) {
                    queue.add(i);
                    visited[i] = true;
                }
            }
        }
    }

    public static void dfs(int idx) throws IOException {
       for(int i = 1; i < visited.length; i++) {
           if(visited[i] || graph[idx][i] == 0) {
               continue;
           }
           bw.write(String.valueOf(i) + " ");
           visited[i] = true;
           dfs(i);
       }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer stk = new StringTokenizer(br.readLine());

        int N = Integer.parseInt(stk.nextToken());
        int M = Integer.parseInt(stk.nextToken());
        int V = Integer.parseInt(stk.nextToken());
        int a, b;

        graph = new int[N + 1][N + 1];
        visited = new boolean[N + 1];

        for(int i = 0; i < M; i++) {
            stk = new StringTokenizer(br.readLine());
            a = Integer.parseInt(stk.nextToken());
            b = Integer.parseInt(stk.nextToken());

            graph[a][b] = 1;
            graph[b][a] = 1;
        }

        visited[V] = true;
        bw.write(String.valueOf(V) + " ");
        dfs(V);
        visited = new boolean[N + 1];
        bw.newLine();
        bfs(V);

        bw.flush();
        bw.close();
    }
}

* dfs를 재귀적 방법으로 사용할때는 1번 노드부터 탐색하기 위해서는 dfs 호출전에 1번노드를 미리 찍고 시작해야된다

 

 

3. BFS 활용 - 1. 백준 2667

package CodingTestMemory.BJ.BFSDFS.P2667;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class P2667 {

    static class Node {
        int y, x;
        Node (int y, int x) {
            this.y = y;
            this.x = x;
        }

    }

    static int[][] graph;
    static boolean[][] visited;
    static int[] dx = {-1, 0, 1, 0};
    static int[] dy = {0, 1, 0, -1};
    static int N;

    public static int bfs(int y, int x) {
        int cnt = 0;
        Queue<Node> queue = new LinkedList<>();
        queue.add(new Node(y, x));
        visited[y][x] = true;
        while(!queue.isEmpty()) {
            Node e = queue.poll();
            cnt++;
            for(int i = 0; i < 4; i++) {
                int nx = e.x + dx[i];
                int ny = e.y + dy[i];
                if(nx < 0 || ny < 0 || nx >= N || ny >= N) {
                    continue;
                }
                if(visited[ny][nx] || graph[ny][nx] == 0) {
                    continue;
                }
                visited[ny][nx] = true;
                queue.add(new Node(ny, nx));
            }
        }
        return cnt;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(br.readLine());
        String input;

        graph = new int[N][N];
        visited = new boolean[N][N];
        List list = new LinkedList();

        for(int j = 0; j < N; j++) { // 데이터 입력
            input = br.readLine();
            for(int i = 0; i < input.length(); i++) {
                graph[j][i] = (int) input.charAt(i) - 48;
            }
        }
        for(int j = 0; j < N; j++) {
            for(int i = 0; i < N; i++) { // 시작점 탐색 후 bfs
                if(graph[j][i] == 1 && !visited[j][i]) {
                    list.add(bfs(j, i));
                }
            }
        }
        list.sort(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return (int)o1 - (int) o2;
            }
        });
        //Collections.sort(list); // 연결리스트를 정렬하기 위해서는 Collections.sort 를 사용하면 더 편리

        System.out.println(list.size()); // 결과 출력부분
        for(int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }
}

* 연결리스트를 정렬하는 방법

1. Linkedlist.sort() 사용. Comparator를 직접 정의해 줘야함

2. Collections.sort() 사용. 필요시 Comparator를 직접 정의해서 사용하면 됨.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함