
그래프는
정점과간선으로 이루어진 자료구조 입니다.
그래프와 트리는 굉장히 유사합니다. 트리와 차이점은 그래프는 Cyclic하고 트리는 UnCyclic 합니다.
Cyclic이 어떤 차이를 가져올까요?
트리는 한 노드에서 다른 노드로 향하는 방법이 1가지입니다. 그러나 그래프는 Cyclic 하기때문에 한 노드에서 다른 노드로 갈 수 있는 방법이 여러가지 존재할 수 있습니다.

그래프는 무방향 그래프 와 방향 그래프 2가지 종류가 있습니다. 0 노드에서 1 노드로 갈 때 무방향 은 0 -> 1 , 1 -> 0 둘 다 가능합니다. 그러나 방향 그래프 는 1 -> 0 만 가능합니다.
그래프에 대해 깊은 학습을 위해 그래프 구조에 대해 알아보겠습니다.
무방향의 그래프는 A - B 와 B - A 는 같습니다. 그리고 (A, B) 로 표현합니다.
방향 그래프는 A -> B, B -> A 는 서로 다릅니다. 표현은 <A, B> 로 합니다.
각 노드에 방문했는지 여부를 체크할
배열과스택을 이용하여 구현합니다.
각 노드에 방문했는지 여부를 체크할
배열과큐를 이용하여 구현합니다.
간선 정보의
확인과업데이트가 빠릅니다O(1). 그러나메모리 공간을 차지합니다.
메모리 사용량이 상대적으로 적고, 노드의
추가삭제가 빠릅니다. 그러나확인이 상대적으로 오래 걸립니다.
인접 행렬
노드의 개수가 적고 간선의 수가 많을 때는 인접행렬이 유리합니다. 밀집 그래프, 완전 그래프와 같은 형태가 유리합니다.
인접 리스트
노드의 개수가 많고 간선의 수가 적을 때 유리합니다. 희소 그래프와 같은 형태가 유리합니다.
class MyGraphMatrix {
char[] vertices;
int[][] adjMat;
int elemCnt;
public MyGraphMatrix(){}
public MyGraphMatrix(int size){
this.vertices = new char[size];
this.adjMat = new int[size][size];
this.elemCnt = 0;
}
public boolean isFull() {
return this.elemCnt == this.vertices.length;
}
public void addVertex(char data) {
if (isFull()) {
System.out.println("Graph is Full!!!");
return;
}
this.vertices[elemCnt++] = data;
}
public void addEdge(int x, int y) {
this.adjMat[x][y] = 1;
this.adjMat[y][x] = 1;
}
public void addDirectedEdge(int x, int y) {
this.adjMat[x][y] = 1;
}
public void deleteEdge(int x, int y) {
this.adjMat[x][y] = 0;
this.adjMat[y][x] = 0;
}
public void deleteDirectedEdge(int x, int y) {
this.adjMat[x][y] = 0;
}
public void printAdjacentMatrix() {
System.out.print(" ");
for (char item : this.vertices) {
System.out.print(item + " ");
}
System.out.println();
for (int i = 0; i < this.elemCnt; i++) {
System.out.print(this.vertices[i] + " ");
for (int j = 0; j < this.elemCnt; j++) {
System.out.print(this.adjMat[i][j] + " ");
}
System.out.println();
}
}
}
public class Prac1 {
public static void main(String[] args) {
// TEST CODE
MyGraphMatrix graph = new MyGraphMatrix(4);
graph.addVertex('A');
graph.addVertex('B');
graph.addVertex('C');
graph.addVertex('D');
graph.addEdge(0, 1);
graph.addEdge(0, 2);
graph.addEdge(1, 2);
graph.addEdge(1, 3);
graph.addEdge(2, 3);
graph.printAdjacentMatrix();
}
}
class Node {
int id;
Node next;
public Node(int id, Node next) {
this.id = id;
this.next = next;
}
}
class MyGraphList {
char[] vertices;
Node[] adjList;
int elemCnt;
public MyGraphList() {}
public MyGraphList(int size) {
this.vertices = new char[size];
this.adjList = new Node[size];
this.elemCnt = 0;
}
public boolean isFull() {
return elemCnt == this.vertices.length;
}
public void addVertex(char data) {
if (isFull()) {
System.out.println("Graph is Full!!");
return;
}
this.vertices[elemCnt++] = data;
}
public void addEdge(int x, int y) {
this.adjList[x] = new Node(y, this.adjList[x]);
this.adjList[y] = new Node(x, this.adjList[y]);
}
public void addDirectedEdge(int x, int y) {
this.adjList[x] = new Node(y, this.adjList[x]);
}
public void printDirectedEdge() {
for (int i = 0; i < this.elemCnt; i++) {
System.out.print(this.vertices[i] + " : ");
Node cur = this.adjList[i];
while (cur != null) {
System.out.print(this.vertices[cur.id] + " ");
cur = cur.next;
}
System.out.println();
}
}
}
public class Prac2 {
public static void main(String[] args) {
// Test Code
MyGraphList graph = new MyGraphList(4);
graph.addVertex('A');
graph.addVertex('B');
graph.addVertex('C');
graph.addVertex('D');
graph.addEdge(0, 1);
graph.addEdge(0, 2);
graph.addEdge(1, 2);
graph.addEdge(1, 3);
graph.addEdge(2, 3);
graph.printDirectedEdge();
}
}
class MyGraphMatrix2 extends MyGraphMatrix {
public MyGraphMatrix2(int size) {
super(size);
}
public void dfs(int id) {
boolean[] visited = new boolean[this.elemCnt];
Stack<Integer> stack = new Stack<>();
stack.push(id);
visited[id] = true;
while (!stack.isEmpty()) {
int curId = stack.pop();
System.out.print(this.vertices[curId] + " ");
for (int i = this.elemCnt - 1; i >= 0; i--) {
if (this.adjMat[curId][i] == 1 && visited[i] == false) {
stack.push(i);
visited[i] = true;
}
}
}
System.out.println();
}
public void bfs(int id) {
boolean[] visited = new boolean[this.elemCnt];
Queue<Integer> queue = new LinkedList<>();
queue.offer(id);
visited[id] = true;
while (!queue.isEmpty()) {
int curId = queue.poll();
System.out.print(this.vertices[curId] + " ");
for (int i = this.elemCnt - 1; i >= 0; i--) {
if (this.adjMat[curId][i] == 1 && visited[i] == false) {
queue.offer(i);
visited[i] = true;
}
}
}
System.out.println();
}
}
class MyGraphList2 extends MyGraphList {
public MyGraphList2(int size) {
super(size);
}
public void dfs(int id) {
boolean[] visited = new boolean[this.elemCnt];
Stack<Integer> stack = new Stack<>();
stack.push(id);
visited[id] = true;
while (!stack.isEmpty()){
int cruId = stack.pop();
System.out.print(this.vertices[cruId] + " ");
Node cur = this.adjList[cruId];
while (cur != null) {
if (visited[cur.id] == false) {
stack.push(cur.id);
visited[cur.id] = true;
}
cur = cur.next;
}
}
System.out.println();
}
public void bfs(int id) {
boolean[] visited = new boolean[this.elemCnt];
Queue<Integer> queue = new LinkedList<>();
queue.offer(id);
visited[id] = true;
while (!queue.isEmpty()) {
int cruId = queue.poll();
System.out.print(this.vertices[cruId] + " ");
Node cur = this.adjList[cruId];
while (cur != null) {
if (visited[cur.id] == false) {
queue.offer(cur.id);
visited[cur.id] = true;
}
cur = cur.next;
}
}
System.out.println();
}
}