All :L

[DataStructure] 그래프 본문

STUDY/DataStructure

[DataStructure] 그래프

ofijwe 2024. 10. 27. 13:34
반응형

[그래프의 종류와 구현]

그래프

  • 그래프(Graph) : 정점이라 불리는 데이터를 간선 혹은 링크로 연결한 형태
    • 데이터 간의 연결 관계를 표현
  • 연결 그래프(connected graph) : 임의의 두 정점 사이의 경로가 존재하는 그래프
  • 비연결 그래프(disconnected graph) : 정점 사이에 경로가 존재하지 않을 수 있는 그래프
  • 방향 그래프(directed graph) : 간선에 방향이 있는 그래프
  • 무방향 그래프(undirected graph) : 간선에 방향이 없는 그래프
  • 가중치 그래프(weighted graph) : 간선에 가중치가 부여된 그래프
    • 비용(cost) : 간선에 부여된 값
  • 서브 그래프(subgraph) : 특정 그래프의 정점과 간선의 일부분으로 이루어진 그래프

인접 행렬 기반 그래프 표현

  • N X N 크기의 행렬로 그래프 표현하는 방법

    • 무방향 그래프

      image (11)

    • 방향 그래프

      image (10)

인접 리스트 기반 그래프 표현

  • 그래프의 특정 정점과 연결된 정점들을 연결 리스트로 표현하는 방법

    image (9)


[깊이 우선 탐색과 너비 우선 탐색]

깊이 우선 탐색

  • DFS(Depth-First Search) : 그래프에서 더 이상 방문 가능한 정점이 없을 때까지 최대한 깊이 탐색하기를 반복하는 탐색 방법

    import java.util.*;
    public class DFSExample {
    private static void dfs(int node, boolean[] visited, List<List<Integer>> graph) {
    // 현재 노드를 방문 처리
    visited[node] = true;
    System.out.print(node + " ");
    // 인접한 노드를 재귀적으로 방문
    for (int neighbor : graph.get(node)) {
    if (!visited[neighbor]) {
    dfs(neighbor, visited, graph);
    }
    }
    }
    public static void main(String[] args) {
    int n = 5; // 노드 개수
    List<List<Integer>> graph = new ArrayList<>();
    for (int i = 0; i <= n; i++) {
    graph.add(new ArrayList<>());
    }
    // 그래프 연결 정보 설정
    graph.get(1).add(2);
    graph.get(1).add(3);
    graph.get(2).add(4);
    graph.get(3).add(5);
    boolean[] visited = new boolean[n + 1];
    System.out.print("DFS: ");
    dfs(1, visited, graph);
    }
    }

너비 우선 탐색

  • BFS(Breadth-First Search) : 그래프에서 더 이상 방문 가능한 정점이 없을 때까지 최대한 넓게 탐색하기를 반복하는 탐색 방법

    import java.util.*;
    public class BFSExample {
    private static void bfs(int start, List<List<Integer>> graph) {
    Queue<Integer> queue = new LinkedList<>();
    boolean[] visited = new boolean[graph.size()];
    queue.add(start);
    visited[start] = true;
    while (!queue.isEmpty()) {
    int node = queue.poll();
    System.out.print(node + " ");
    for (int neighbor : graph.get(node)) {
    if (!visited[neighbor]) {
    queue.add(neighbor);
    visited[neighbor] = true;
    }
    }
    }
    }
    public static void main(String[] args) {
    int n = 5; // 노드 개수
    List<List<Integer>> graph = new ArrayList<>();
    for (int i = 0; i <= n; i++) {
    graph.add(new ArrayList<>());
    }
    // 그래프 연결 정보 설정
    graph.get(1).add(2);
    graph.get(1).add(3);
    graph.get(2).add(4);
    graph.get(3).add(5);
    System.out.print("BFS: ");
    bfs(1, graph);
    }
    }

[최단 경로 알고리즘]

최단 경로 알고리즘

  • 최단 경로 알고리즘 : 한 정점에서 목적지 정점까지 이르는 가중치의 합이 최소가 되는 경로를 결정하는 알고리즘
  • 실생활 예
    • 지도 서비스 (원하는 목적지까지의 최단 거리)
    • 컴퓨터 네트워크

다익스트라 알고리즘

  • Dijkstra’s Algorithm : 간선의 가중치가 음이 아닌 수라는 가정 하에 사용 가능한 최단 경로 알고리즘

  • 동작 방식

    • 시작 정점 제외한 정점 초기화

    • (시작) 정점 방문

    • 경로 상 가중치 합과 최단 거리 테이블 상 값 비교

    • 최단 거리 테이블 갱신 가능하면 갱신

    • 방문하지 않은 정점 중 최단 거리가 가장 작은 정점 방문

    • 더 이상 방문할 정점이 없을 때까지 반복

      import java.util.*;
      public class DijkstraExample {
      static class Node implements Comparable<Node> {
      int vertex;
      int distance;
      public Node(int vertex, int distance) {
      this.vertex = vertex;
      this.distance = distance;
      }
      // 우선순위 큐에서 거리 오름차순으로 정렬하기 위한 비교 함수
      @Override
      public int compareTo(Node other) {
      return Integer.compare(this.distance, other.distance);
      }
      }
      public static int[] dijkstra(int start, List<List<Node>> graph, int n) {
      PriorityQueue<Node> pq = new PriorityQueue<>();
      int[] distances = new int[n + 1];
      Arrays.fill(distances, Integer.MAX_VALUE);
      distances[start] = 0;
      pq.add(new Node(start, 0));
      while (!pq.isEmpty()) {
      Node current = pq.poll();
      int currentVertex = current.vertex;
      int currentDistance = current.distance;
      // 이미 처리된 노드의 최단 경로보다 큰 경우 무시
      if (currentDistance > distances[currentVertex]) continue;
      // 인접 노드 확인
      for (Node neighbor : graph.get(currentVertex)) {
      int newDist = distances[currentVertex] + neighbor.distance;
      // 더 짧은 경로가 발견되면 갱신
      if (newDist < distances[neighbor.vertex]) {
      distances[neighbor.vertex] = newDist;
      pq.add(new Node(neighbor.vertex, newDist));
      }
      }
      }
      return distances;
      }
      public static void main(String[] args) {
      int n = 5; // 노드 개수
      List<List<Node>> graph = new ArrayList<>();
      for (int i = 0; i <= n; i++) {
      graph.add(new ArrayList<>());
      }
      // 그래프 연결 설정 (노드, 가중치)
      graph.get(1).add(new Node(2, 2));
      graph.get(1).add(new Node(3, 5));
      graph.get(2).add(new Node(3, 3));
      graph.get(2).add(new Node(4, 1));
      graph.get(3).add(new Node(4, 2));
      graph.get(4).add(new Node(5, 1));
      int start = 1; // 시작 노드
      int[] distances = dijkstra(start, graph, n);
      System.out.println("노드 " + start + "에서 각 노드까지의 최단 거리:");
      for (int i = 1; i <= n; i++) {
      System.out.println("노드 " + i + " : " + distances[i]);
      }
      }
      }

💡 참고 자료

반응형

'STUDY > DataStructure' 카테고리의 다른 글

[DataStructure] 트리  (0) 2024.10.25
[DataStructure] 해시 테이블  (0) 2024.10.23
[DataStructure] 스택과 큐  (0) 2024.10.21
[DataStructure] 배열과 연결 리스트  (0) 2024.10.19
[DataStructure] 자료구조의 큰 그림  (0) 2024.10.17
Comments