컴퓨터과학/자료구조&알고리즘
[자료구조와 알고리즘] 그래프 표현방법
PureStack
2021. 12. 16. 23:56
인접행렬 (Adjacency Matrix)
- G=(V, E)는 정점의 수가 n인 그래프
- 인접행렬: n x n인 2차원 배열
- 행, 열 => 그래프의 정점
- 간선 (Vi, Vj) ∈ E(G) => a[i][j] = 1 (인접한 경우)
- 간선 (Vi, Vj) ∉ E(G) => a[i][j] = 0 (인접하지 않은 경우)
- 무방향 그래프 : 어떤 정점 i의 차수는 그 행 또는 열의 합
- 방향 그래프 : 행의 합은 진출차수, 열의 합은 진입차수
- 정점 0의 인접 정점 : 1, 2
- 정점 1의 인접 정점 : 0, 3
- 정점 2의 인접 정점 : 0. 3
- 정점 3의 인접 정점 : 1, 2
인접행렬 소스코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
class Graph {
private int[][] adjGraph;
public Graph(int size) { // 그래프 초기화
this.adjGraph = new int[size][size];
}
public void insertDouble(int v1, int v2) { // 무방향 그래프 간선 추가
adjGraph[v1][v2] = adjGraph[v2][v1] = 1;
}
public void insertSingle(int v1, int v2) { // 방향 그래프 간선 추가
adjGraph[v1][v2] = 1;
}
public void printGraph() { // 그래프 출력
for(int i=0;i<adjGraph.length;i++) {
for(int j=0;j<adjGraph[i].length;j++) {
System.out.print(adjGraph[i][j]+" ");
}
System.out.println();
}
}
}
public class GraphMatrix {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int size = 4;
int edge = 4;
Graph arr = new Graph(size);
for(int i=0;i<edge;i++) {
String str = br.readLine();
StringTokenizer st = new StringTokenizer(str, " ");
int v1 = Integer.parseInt(st.nextToken());
int v2 = Integer.parseInt(st.nextToken());
arr.insertDouble(v1, v2);
// 방향 그래프일 경우에는 arr.insertSingle(v1, v2);
}
/*
입력(무방향 그래프)
0 1, 정점 0과 1 사이의 간선 추가
0 2, 정점 0과 2 사이의 간선 추가
1 3, 정점 1과 3 사이의 간선 추가
2 3, 정점 2와 3 사이의 간선 추가
*/
System.out.println();
arr.printGraph();
/*출력
0 1 1 0
1 0 0 1
1 0 0 1
0 1 1 0
*/
}
}
- 인접행렬의 수행 시간 : 최소 O(n2)
- 인접행렬의 단점
- n개의 정점을 가지는 그래프를 항상 n x n개의 메모리를 사용해야 한다.
- 정점의 개수에 비해 간선의 개수가 적은 희소 그래프에 대한 인접 행렬은 희소 행렬이 되므로 메모리의 낭비 발생
인접 리스트 (Adjacency Lists)
- 각 정점에 대한 인접 정점들을 연결하여 만든 단순 연결 리스트 -> 인접 행렬의 각 행을 연결 리스트로
- 각 정점의 차수만큼 노드를 연결
- 리스트 내의 노드들은 인접 정점에 대하여 오름차순으로 연결
- 인접 리스트의 각 노드
- 정점과 다음 인접 정점을 연결하는 링크 필드
- 정점의 헤드 노드
- 정점에 대한 리스트의 시작을 표현
- n개의 정점, e개의 간선을 가진 무향 그래프의 인접 리스트
- 헤드 노드 배열의 크기 : n
- 연결하는 노드의 수 : 2e
- 각 정점의 헤드에 연결된 노드의 수 : 정점의 차수
- n개의 정점, e개의 간선을 가진 방향 그래프의 인접 리스트
- 헤드 노드 배열의 크기 : n
- 연결하는 노드의 수 : e
- 각 정점의 헤드에 연결된 노드의 수 : 정점의 진출 차수
- 역인접리스트 : 진입 차수
- 위의 그림에서 정점 0에는 노드 2개가 있는데, 이는 정점 0의 차수는 2라는 의미이다.
- 인접 리스트 소스 코드
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.StringTokenizer;
class Graph {
private ArrayList<ArrayList<Integer>> listGraph;
public Graph(int size) {
this.listGraph = new ArrayList<ArrayList<Integer>>();
for(int i=0;i<=size;i++) {
listGraph.add(new ArrayList<>());
}
}
public void insertDouble(int v1, int v2) {
listGraph.get(v1).add(v2);
listGraph.get(v2).add(v1);
}
public void insertSingle(int v1, int v2) {
listGraph.get(v1).add(v2);
}
public void printGraph() {
for(int i=0;i<listGraph.size()-1;i++) {
System.out.print("Vertex "+i+" 인접리스트");
for(int j=0;j<listGraph.get(i).size();j++) {
System.out.print("-> " + listGraph.get(i).get(j));
}
System.out.println();
}
}
}
public class GraphList {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
Graph graph = new Graph(4); // 정점 4개 있는 그래프 생성
int edge = 4; // 간선의 개수 4개
for(int i=0;i<edge;i++) {
String str = br.readLine();
StringTokenizer st = new StringTokenizer(str, " ");
int v1 = Integer.parseInt(st.nextToken());
int v2 = Integer.parseInt(st.nextToken());
graph.insertDouble(v1, v2);
/*
입력(무방향 그래프)
0 1
0 2
1 3
2 3
*/
}
graph.printGraph();
/*
출력
Vertex 0 인접리스트-> 1-> 2
Vertex 1 인접리스트-> 0-> 3
Vertex 2 인접리스트-> 0-> 3
Vertex 3 인접리스트-> 1-> 2
*/
}
}
참고자료
https://freestrokes.tistory.com/87
Java 인접행렬과 인접리스트를 이용하여 그래프 구현하기
Java 인접행렬과 인접리스트를 이용하여 그래프 구현하기 Java로 인접행렬과 인접리스트를 만들어 그래프를 구현하는 방법에 대해 알아보겠습니다. 1. 그래프 (Graph) 수학적 정의로 그래프는 객
freestrokes.tistory.com
[자료 구조] Java로 그래프 구현하기 :: 인접 리스트로 구현한 그래프
To Do 인접 리스트란? 가중치가 없는 그래프를 인접 리스트로 구현하기 가중치가 있는 그래프를 인접 리스트로 구현하기 지난 시간에 우리는 인접 행렬로 그래프를 그리는 시간을 가졌다. 오늘은
wonit.tistory.com