그래프
여러 개체들이 연결되어 있는 자료구조
탐색
특정 개체를 찾기 위한 알고리즘
경로탐색 유형 (최단거리, 시간)
a~b지점까지 가는데 최소 거리/최단 시간 구하기
네트워크 유형 (연결)
여러 개체들이 주어진 상태에서 연결되어 있는 그룹의 개수를 구하거나 두 개체가 같은 네트워크 안에서 연결되어 있는지 확인하기
조합 유형 (모든 조합 만들기)
여러가지의 조합을 모두 만들고 비교하기
DFS : 드라마 하나를 끝까지 보고 다른 드라마를 본다.
BFS : 여러 개의 드라마를 한편씩 본다.
루트노드에서 시작해 다음 분기로 넘어가기 전 해당 분기를 완벽하게 탐색하는 방식으로 스택 또는 재귀함수로 구현한다.
장점
최단 경로를 빠르게 찾을 수 있다.
단점
경로가 매우 길 경우, 탐색할 가지 수가 급격히 증가함에 따라 많은 기억 공간이 필요하다.
경로가 존재하지 않는 비연결 그래프일 경우, 모든 그래프를 탐색한 후 실패로 끝난다.
루트노드에서 시작해 인접한 노드를 먼저 탐색하는 방식으로 시작 정점으로부터 가까운 정점을 먼저 방문하고 멀리 떨어져 있는 정점을 나중에 방문하는 순회 방법이다. 큐를 이용해서 구현한다.
장점
현 경로상의 노드를 기억하기 때문에 적은 메모리를 사용한다.
찾으려는 노드가 깊은 단계에 있는 경우, BFS보다 빠르다.
단점
경로가 존재하지 않아도 끝날 때까지 탐색한다.
최단 경로를 찾을 수 없다.
C++
const int MAX = 100001;
// 방문 배열. visited[node] = true이면 node는 방문이 끝난 상태이다.
bool visited[MAX];
// graph는 인접 리스트, current는 현재 노드
void dfs(const vector<int> graph[], int current) {
visited[current] = true; // current 방문
// current의 인접 노드를 확인한다. 이 노드를 next라고 하자.
for(int next: graph[current]) {
// 만일 next에 방문하지 않았다면 next 방문
if(!visited[next]) {
dfs(graph, next);
}
}
}
C#
using System;
public class Solution
{
int MAX = 100001;
// 방문 배열: true이면 해당 노드는 이미 방문을 한 상태
bool[] visited = new bool[MAX];
// graph는 인접 리스트, current는 현재 노드
void DFS(List<int[]> graph, int current)
{
visited[current] = true;
foreach (int next in graph[current])
{
if (visited[current] == false)
{
DFS(graph, next);
}
}
}
}
C++
const int MAX = 100001;
queue<int> q;
// 방문 배열. visited[node] = true이면 node는 방문이 끝난 상태이다.
bool visited[MAX];
// graph는 인접 리스트, source는 시작 노드
void bfs(const vector<int> graph[], int source) {
// source 방문한다.
q.push(source);
visited[source] = true;
// 큐가 빌 때까지 반복한다.
while(!q.empty()) {
// 큐에서 노드를 하나 빼 온다. 이 노드를 current라고 하자.
int current = q.front();
q.pop();
// current의 인접 노드들을 확인한다. 이 각각의 노드를 next라고 한다.
for(int next: graph[current]) {
// 만일 next에 방문하지 않았다면 next 방문한다.
if(!visited[next]) {
q.push(next);
visited[next] = true;
}
}
}
}
C#
using System;
public class Solution
{
int MAX = 100001;
queue<int> q;
bool[] visited = new bool[MAX];
// graph는 인접 리스트, source는 시작 노드
void bfs(List<int[]> graph, int source)
{
// source 방문한다.
q.push(source);
visited[source] = true;
// 큐가 빌 때까지 반복한다.
while (!q.empty())
{
// 큐에서 노드를 하나 빼 온다. 이 노드를 current라고 하자.
int current = q.front();
q.pop();
// current의 인접 노드들을 확인한다. 이 각각의 노드를 next라고 한다.
foreach (int next in graph[current])
{
// 만일 next에 방문하지 않았다면 next 방문한다.
if (!visited[next])
{
q.push(next);
visited[next] = true;
}
}
}
}
}