[자료구조] 그래프
그래프는 정점이라고 불리는 노드들의 집합 V와 간선이라고 불리는 정점들의 쌍의 집합 E로 이루어진 쌍(V, E)이다.
그래프의 표현
- 인접행렬 - 연결된 행렬을 1로, 공간 V^2, v에 종속된 간선찾기, V
- 인접리스트 - 연결된 정점은 전부 연결리스트로, 공간 E+V, v에 종속된 간선찾기, Degree(v)
그래프 탐색 DFS BFS
class Vertex {
public int label;
public boolean visited;
public Vertex(int label){
this.label = label;
this.visited = false;
}
}
class Graph{
private int adjMaxtrix[][];
private Vertex vertexList[];
private Stack<Integer> stack;
private Queue<Integer> queue;
public Graph(){
adjMatrix = new int[20][20];
stack = new Stack();
queue = new Queue();
}
// 시간복잡도 O(V^2), 인접리스트로 하면 O(V+E)
public void dfs() {
vertexList[0].visited = true;
displayVertex(0);
stack.push(0);
while(!stack.isEmpty()){
int v = getAdjUnvisitedVertex(stack.peek());
if(v == -1){
stack.pop();
} else {
vertexList[v].visited = true;
displayVertex(v);
stack.push(v);
}
}
}
public dfsR(int n){
vertexList[n].visited = true;
displayVertex(n);
for(int i = 0; i < vertexList.length; i++){
if(adjMatrix[v][i] == 1 && vertexList[i].visited == false){
dfsR(i);
}
}
}
// 시간복잡도 O(V^2), 인접리스트는 O(V+E)
public bfs(){
vertexList[0].visited = true;
displayVertex(0);
queue.enqueue(0);
int v2;
while(!queue.isEmpty())[
int v1 = queue.dequeue();
while((v2 = getAdjUnvisitedVertex(v1)) != -1){
vertexList[v2].visited = true;
displayVertex(v2);
queue.enqueue(v2);
}
}
}
public int getAdjUnvisitedVertex(int v){
for(int i = 0; i < vertexList.length; i++){
if(adjMatrix[v][i] == 1 && vertexList[i].visited == false){
return i;
}
}
return -1;
}
}
BFS와 DFS를 비교하면 DFS의 큰 장점은 BFS보다 훨씬 적은 메모리를 필요로 한다는 것이다. 왜냐하면 각 레벨의 모든 자식 포인터를 저장할 필요가 없기 때문이다. 데이터에 따라, 추구하는 목적에 따라 DFS와 BFS 중 하나를 선택하면 된다.
적용사례
신장 트리, 연결된 구성 요소, 경로, 사이클 - DFS, BFS
최단 거리 - BFS
메모리 공간 최소 사용 - DFS