vertex(정점)와 edge(간선)로 구성된 한정된 자료구조를 의미
종류 | 방향성 | 순환성 | 루트 여부 | 노드 관계 | 모델 |
---|---|---|---|---|---|
그래프 | 방향 그래프 또는 무방향 그래프 | 순환 및 비순환 | 루트 노드 없음 | 부모 자식 관계 없음 | 네트워크 모델 |
트리 | 방향 그래프 | 비순환 | 루트 노드 존재 | 부모 자식 관계 | 계층 모델 |
2차원 배열로 그래프의 연결 관계를 표현하는 방식
public class AdjacencyMatrix {
public static final int INF = Integer.MAX_VALUE;
public static int[][] graph = {
{0, 7, 5},
{7, 0, INF},
{5, INF, 0}
};
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(graph[i][j] + " ");
}
System.out.println();
}
}
}
리스트로 그래프의 연결 관계를 표현하는 방식
class Vertex {
private int index;
private int distance;
public Vertex(int index, int distance) {
this.index = index;
this.distance = distance;
}
public void show() {
System.out.print("(" + this.index + "," + this.distance + ") ");
}
}
public class AdjacencyList {
public static ArrayList<ArrayList<Vertex>> graph = new ArrayList<>();
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
graph.add(new ArrayList<>());
}
graph.get(0).add(new Vertex(1, 7));
graph.get(0).add(new Vertex(2, 5));
graph.get(1).add(new Vertex(0, 7));
graph.get(2).add(new Vertex(0, 5));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < graph.get(i).size(); j++) {
graph.get(i).get(j).show();
}
System.out.println();
}
}
}
하나의 정점으로부터 시작하여 차례대로 모든 정점들을 한 번씩 방문
특정한 경로를 탐색하다가 특정 상황에서 최대한 깊숙이 들어가서 노드를 방문 후,
다시 돌아가 다른 경로로 탐색하는 알고리즘
깊이 우선 탐색 (DFS)의 특징
0 → 2 → 3 → 4 → 1
public class GraphMatrix {
static int edge;
static int vertex;
static int[][] graph;
static boolean[] visited;
public static void main(String[] args) {
vertex = 5;
edge = 7;
graph = new int[vertex + 1][vertex + 1];
visited = new boolean[vertex + 1];
addEdge(1, 2);
addEdge(1, 3);
addEdge(2, 3);
addEdge(2, 4);
addEdge(2, 5);
addEdge(3, 4);
addEdge(4, 5);
dfs(1);
}
private static void addEdge(int i1, int i2) {
graph[i1][i2] = 1;
graph[i2][i1] = 1;
}
// 재귀
private static void dfs(int i) {
visited[i] = true;
System.out.println(i + " ");
for (int j = 1; j < vertex + 1; j++) {
if (graph[i][j] == 1 && !visited[j]) {
dfs(j);
}
}
}
}
class Vertex {
int data;
List<Vertex> adjacent;
boolean marked;
Vertex (int data) {
this.data = data;
this.marked = false;
adjacent = new ArrayList<>(); // or LinkedList
}
}
public class GraphList {
Vertex[] vertexes;
GraphList (int size) {
vertexes = new Vertex[size];
for (int i = 0; i < size; i++) {
vertexes[i] = new Vertex(i);
}
}
void addEdge(int i1, int i2) {
Vertex n1 = vertexes[i1];
Vertex n2 = vertexes[i2];
if (!n1.adjacent.contains(n2)) {
n1.adjacent.add(n2);
}
if (!n2.adjacent.contains(n1)){
n2.adjacent.add(n1);
}
}
void dfs() {
dfs(0);
}
// 스택
void dfs(int index) {
Vertex root = vertexes[index];
Stack<Vertex> stack = new Stack<>();
stack.push(root);
root.marked = true;
while (!stack.isEmpty()) {
Vertex r = stack.pop();
for (Vertex n : r.adjacent) {
if (!n.marked) {
n.marked = true;
stack.push(n);
}
}
visit(r);
}
}
private void dfsR(Vertex r) {
if (r == null) return;
r.marked = true;
visit(r);
for (Vertex n : r.adjacent) {
if (!n.marked)
dfsR(n);
}
}
void dfsR(int index) {
Vertex r = vertexes[index];
dfsR(r);
}
// 재귀
void dfsR() {
dfsR(0);
}
void visit(Vertex n) {
System.out.print(n.data + " ");
}
public static void main(String[] args) {
GraphList g = new GraphList(5);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(1, 3);
g.addEdge(1, 4);
g.addEdge(2, 3);
g.addEdge(3, 4);
g.dfs();
}
}
루트 노드(혹은 다른 임의의 노드)에서 시작해서 인접한 노드를 먼저 탐색
너비 우선 탐색 (BFS)의 특징
0 → 1 → 2 → 3 → 4
class Vertex {
int data;
List<Vertex> adjacent;
boolean marked;
Vertex (int data) {
this.data = data;
this.marked = false;
adjacent = new ArrayList<>(); // or LinkedList
}
}
public class GraphList {
Vertex[] vertexes;
GraphList (int size) {
vertexes = new Vertex[size];
for (int i = 0; i < size; i++) {
vertexes[i] = new Vertex(i);
}
}
void addEdge(int i1, int i2) {
Vertex n1 = vertexes[i1];
Vertex n2 = vertexes[i2];
if (!n1.adjacent.contains(n2)) {
n1.adjacent.add(n2);
}
if (!n2.adjacent.contains(n1)){
n2.adjacent.add(n1);
}
}
void visit(Vertex n) {
System.out.print(n.data + " ");
}
void bfs() {
bfs(0);
}
void bfs(int i) {
Vertex root = vertexes[i];
Queue<Vertex> queue = new LinkedList<>();
queue.add(root);
root.marked = true;
while(!queue.isEmpty()) {
Vertex r = queue.poll();
for (Vertex v : r.adjacent) {
if (!v.marked) {
v.marked = true;
queue.add(v);
}
}
visit(r);
}
}
public static void main(String[] args) {
GraphList g = new GraphList(5);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(1, 3);
g.addEdge(1, 4);
g.addEdge(2, 3);
g.addEdge(3, 4);
g.bfs(); // 0 1 2 3 4
}
}