DFS
by
DFS
C++언어를 사용하고 2가지 방식을 이용하여 DFS를 구현했다.
- 재귀호출방식(인접행렬, 인접리스트)
- 스택방식
방문순서 : A - B - D - E - C -F
A
/ |
B C
/ / |
D - E F
밑의 코드에서
visited[i]는 i노드에 방문했는지 여부를 아는 변수다.
adjacent는 0부터 시작한다.
입력방식
vertex갯수
edge갯수
start_vertex dest_vertex
....
재귀호출방식
인접행렬
#include<iostream>
#include<vector>
using namespace std;
int v_size;//vertex 갯수
vector<vector<int>> adjacent; //인접행렬
vector<bool> visited(v_size+1, false);
void dfs(int here)
{
cout << "visit : " << here << endl;
visited[here] = true;
for (int i = 1; i < v_size+1; i++)
{
if (adjacent[here][i] != 0 && !visited[i])
dfs(i);
}
}
void dfsall() {
//그래프가 여러개일수 있으므로 모든 정점에 대해 수행
visited = vector<bool>(v_size+1, false);
for (int i = 1; i < v_size+1; i++)
{
if (!visited[i])
dfs(i);
}
}
int main()
{
cin >> v_size;
adjacent = vector<vector<int>>(v_size+1, vector<int>(v_size+1, 0));
int e_size;
cin >> e_size;
int s, d;
for (int i = 0; i < e_size; i++)
{
cin >> s >> d;
adjecant[s][d] = 1;
}
dfsall();
return 0;
}
인접행렬
0 1 2 3 4 5 6
0 0 0 0 0 0 0 0
1 0 0 1 1 0 0 0
2 0 0 0 0 1 1 0
3 0 0 0 0 0 0 1
4 0 0 0 0 0 0 0
5 0 0 0 0 0 0 1
6 0 0 0 0 0 0 0
idx 0은 사용하지 않았다.
인접리스트
#include<iostream>
#include<vector>
using namespace std;
int v_size;//vertex 갯수
vector<vector<int>> adjacent; //인접리스트
vector<bool> visited(adjacent.size(), false);
void dfs(int here)
{
cout << "visit : " << here << endl;
visited[here] = true;
for (int i = 0; i <adjacent[here].size(); i++)
{
if (!visited[adjacent[here][i]])
dfs(adjacent[here][i]);
}
}
void dfsall() {
//그래프가 여러개일수 있으므로 모든 정점에 대해 수행
visited = vector<bool>(adjacent.size(), false);
for (int i = 1; i < adjacent.size(); i++)
{
if (!visited[i])
dfs(i);
}
}
int main()
{
cin >> v_size;
adjacent = vector<vector<int>>(v_size+1);
int e_size;
cin >> e_size;
int s, d;
for (int i = 0; i < e_size; i++)
{
cin >> s >> d;
adjacent[s].push_back(d);
}
//인접리스트 출력
cout << endl<<"-----인접 리스트-----" << endl;
for (int i = 1; i < adjacent.size(); i++)
{
cout << i << " :";
for (int j=0; j<adjacent[i].size();j++)
{
cout << adjacent[i][j]<< " ";
}
cout << endl;
}
cout << "-----방문순서-----" << endl;
dfsall();
return 0;
}
인접리스트 1 : 2 3 2 : 4 5 3 : 6 4 : 5 : 6 6 :
입력예시
6 //vertex갯수
6 //edge갯수
1 2
1 3
2 4
2 5
3 6
5 6 //edge
Stack 방식
재귀함수에서 함수호출에 대한 overhead를 줄일 수 있다.
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
int v_size;//vertex 갯수
vector<vector<int>> adjacent; //인접리스트
vector<bool> visited(adjacent.size(), false);
stack<int> mem;
void dfs(int start)
{
int current = start;
mem.push(current);
visited[current] = true;
cout << "visit : " << start << endl;
while (mem.size()) {
current = mem.top();
for (int i = 1; i <= v_size; i++)
{
if (adjacent[current][i] != 0 && !visited[i])
{
current = i;
mem.push(current);
visited[current] = true;
cout << "visit : " << current << endl;
break;
}
else if (i == v_size)
{
mem.pop();
}
}
}
}
void dfsall() {
//그래프가 여러개일수 있으므로 모든 정점에 대해 수행
visited = vector<bool>(v_size+1, false);
for (int i = 1; i < v_size+1; i++)
{
if (!visited[i])
dfs(i);
}
}
int main()
{
cin >> v_size;
adjacent = vector<vector<int>>(v_size + 1, vector<int>(v_size + 1, 0));
int e_size;
cin >> e_size;
int s, d;
for (int i = 0; i < e_size; i++)
{
cin >> s >> d;
adjacent[s][d] = 1;
}
dfsall();
return 0;
}
Stack의변화
1
1 2
1 2 4
1 2 5
1 2 5 6
1 2 5 6 3
참고 : https://algorithms.cf/entry/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B3%B5%EB%B6%802-DFS%EA%B9%8A%EC%9D%B4-%EC%9A%B0%EC%84%A0-%ED%83%90%EC%83%89-C
Subscribe via RSS