Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java로 그래프 데이터 구조 구현하기: 알고리즘과 예제 코드 완벽 정리

이 글에서는 Java로 그래프(Graph) 데이터 구조를 구현하는 방법을 단계별로 살펴봅니다. 그래프는 정점(vertex)과 간선(edge)으로 구성된 자료구조로, 소셜 네트워크 분석, 지도 경로 탐색, 추천 시스템 등 다양한 분야에서 활용됩니다. 이번 예제에서는 내부 클래스인 Edge를 정의하고, 간선 정보를 배열에 저장한 뒤 이를 출력하는 방식으로 그래프를 표현합니다.

참고로 실무에서는 HashMap 컬렉션을 활용해 키-값(key-value) 쌍의 형태로 인접 리스트(adjacency list)를 표현하기도 하지만, 이번 글에서는 가장 기본이 되는 간선 배열 방식을 먼저 익혀보겠습니다.

예제 개요

이번 예제에서 사용할 조건은 다음과 같습니다.

  • 정점의 수: 5개
  • 간선의 수: 8개

프로그램을 실행하면 그래프를 구성하는 노드 간 연결 관계가 아래와 같이 출력됩니다.

A graph object is defined.
The connections between the edges of the Graph are:
1 - 2
1 - 3
1 - 4
2 - 4
2 - 5
3 - 4
3 - 5
4 - 5

알고리즘

  1. 시작
  2. Graph 클래스의 객체(graph_object)를 선언하고, Edge 클래스에는 정수형 변수 source(출발점)와 destination(도착점)를, main 함수에는 vertices_countedges_count를 선언합니다.
  3. 필요한 값을 정의합니다.
  4. 정점의 수와 간선의 수를 초기화합니다.
  5. 앞서 정의한 클래스의 새 인스턴스를 생성합니다.
  6. 생성된 인스턴스에 간선 정보를 초기화합니다.
  7. for 반복문으로 간선 배열을 순회하며 결과를 콘솔에 출력합니다.
  8. 결과를 화면에 표시합니다.
  9. 종료

예제 1: main 함수에서 모든 로직 처리하기

첫 번째 방식은 모든 연산을 main 함수 안에서 한 번에 처리하는 방법입니다. 코드가 비교적 단순하여 그래프 구조의 기본 동작 원리를 이해하기에 적합합니다.

public class Graph {
   class Edge {
      int source, destination;
   }
   int vertices, edges;
   Edge[] edge;
   Graph(int vertices, int edges) {
      this.vertices = vertices;
      this.edges = edges;
      edge = new Edge[edges];
      for(int i = 0; i < edges; i++) {
         edge[i] = new Edge();
      }
   }
   public static void main(String[] args) {
      int vertices_count = 5;
      int edges_count = 8;
      Graph graph_object = new Graph(vertices_count, edges_count);
      System.out.println("A graph object is defined.");
      graph_object.edge[0].source = 1;
      graph_object.edge[0].destination = 2;
      graph_object.edge[1].source = 1;
      graph_object.edge[1].destination = 3;
      graph_object.edge[2].source = 1;
      graph_object.edge[2].destination = 4;
      graph_object.edge[3].source = 2;
      graph_object.edge[3].destination = 4;
      graph_object.edge[4].source = 2;
      graph_object.edge[4].destination = 5;
      graph_object.edge[5].source = 3;
      graph_object.edge[5].destination = 4;
      graph_object.edge[6].source = 3;
      graph_object.edge[6].destination = 5;
      graph_object.edge[7].source = 4;
      graph_object.edge[7].destination = 5;
      System.out.println("The connections between the edges of the Graph are: ");
      for(int i = 0; i < edges_count; i++) {
         System.out.println(graph_object.edge[i].source + " - " + graph_object.edge[i].destination);
      }
   }
}

실행 결과

A graph object is defined.
The connections between the edges of the Graph are:
1 - 2
1 - 3
1 - 4
2 - 4
2 - 5
3 - 4
3 - 5
4 - 5

예제 2: 객체지향 방식으로 메서드 분리하기

두 번째 방식은 간선 연결과 출력 작업을 각각 별도의 메서드(connect_edges, print)로 분리하여 객체지향 프로그래밍(OOP) 스타일로 작성한 것입니다. 역할별로 코드가 나뉘어 있어 가독성과 재사용성이 크게 향상됩니다.

public class Graph {
   class Edge {
      int source, destination;
   }
   int vertices, edges;
   Edge[] edge;
   Graph(int vertices, int edges) {
      this.vertices = vertices;
      this.edges = edges;
      edge = new Edge[edges];
      for(int i = 0; i < edges; i++) {
         edge[i] = new Edge();
      }
   }
   static void print(Graph graph_object,int edges_count){
      System.out.println("The connections between the edges of the Graph are: ");
      for(int i = 0; i < edges_count; i++) {
         System.out.println(graph_object.edge[i].source + " - " + graph_object.edge[i].destination);
      }
   }
   static void connect_edges(Graph graph_object){
      graph_object.edge[0].source = 1;
      graph_object.edge[0].destination = 2;
      graph_object.edge[1].source = 1;
      graph_object.edge[1].destination = 3;
      graph_object.edge[2].source = 1;
      graph_object.edge[2].destination = 4;
      graph_object.edge[3].source = 2;
      graph_object.edge[3].destination = 4;
      graph_object.edge[4].source = 2;
      graph_object.edge[4].destination = 5;
      graph_object.edge[5].source = 3;
      graph_object.edge[5].destination = 4;
      graph_object.edge[6].source = 3;
      graph_object.edge[6].destination = 5;
      graph_object.edge[7].source = 4;
      graph_object.edge[7].destination = 5;
   }
   public static void main(String[] args) {
      int vertices_count = 5;
      int edges_count = 8;
      Graph graph_object = new Graph(vertices_count, edges_count);
      System.out.println("A graph object is defined.");
      connect_edges(graph_object);
      print(graph_object, edges_count);
   }
}

실행 결과

A graph object is defined.
The connections between the edges of the Graph are:
1 - 2
1 - 3
1 - 4
2 - 4
2 - 5
3 - 4
3 - 5
4 - 5

마무리

지금까지 Java에서 그래프 데이터 구조를 구현하는 두 가지 방법을 살펴보았습니다. 첫 번째 예제처럼 main 함수에 모든 로직을 담는 방식은 학습용으로 적합하고, 두 번째 예제처럼 기능을 메서드로 분리하는 방식은 유지보수와 확장에 유리합니다. 기초를 익힌 후에는 HashMap을 활용한 인접 리스트 구현이나 BFS·DFS 같은 그래프 순회 알고리즘으로 확장해 보시기 바랍니다.