图论系列文章
前言
图根据其几种属性可以进行分类:
- 根据边有没有方向:有向图 无向图
- 根据边有没有加权:加权图 非加权图
- 根据图是否连通:连通图 非连通图
- 无向图实质上就是相互指向的有向图
- 非加权图实质上就是权值全部为1的加权图
图的数据结构存储方式,常用的方式有两种,邻接表
与邻接矩阵
,初学者刚开始的时候并不了解这两种存储方式的区别,而实际上这两种方式实质上在操作中基本上是一样的,只是vector中存储元素的遍历方式不同而已。
- 邻接矩阵
vector<vector<int>> vertex;
- 邻接表
vector<list<int>> vertex;
接下来的操作,都将以下图的 图作为标准进行实验。
graph.conf
7 10
0 1
0 2
1 3
2 3
1 4
3 4
3 5
2 5
4 6
5 6
一.DFS递归遍历
int N, C;//N个顶点,C条边
void DFS(vector<vector<int>>& vertex, vector<int>& visited, int i)
{
if (visited[i])
return;
cout << i << "->";
visited[i] = 1;
for (int j = 0; j < N; ++j)
{
if (0 == vertex[i][j])//如果不连通
continue;
DFS(vertex, visited, j);
}
}
int main()
{
cin >> N >> C;
vector<vector<int>> vertex(N, vector<int>(N, 0));
for (int i = 0; i < C; ++i)
{
int m, n;
cin >> m >> n;
vertex[m][n] = 1;//顶点m到顶点n连通
}
//DFS递归法测试
vector<int> visited(N, 0);
//该图可能是非连通的,所有需要遍历每一个点
for (int i = 0; i < N; ++i)
{
if (visited[i])
continue;
DFS(vertex, visited, i);
}
cout << endl;
return 0;
}
二.DFS非递遍历
int N, C;//N个顶点,C条边
void DFS(vector<vector<int>>& vertex, vector<int>& visited, int start)
{
stack<int> stk;
stk.push(start);
while (!stk.empty())
{
int i = stk.top();
visited[i] = 1;
cout << i << "->";
stk.pop();
for (int j = 0; j < N; ++j)
{
if (0 == vertex[i][j] || visited[j])//不连通或者已经访问过
continue;
stk.push(j);
}
}
cout << endl;
}
int main()
{
cin >> N >> C;
vector<vector<int>> vertex(N, vector<int>(N, 0));
for (int i = 0; i < C; ++i)
{
int m, n;
cin >> m >> n;
vertex[m][n] = 1;//顶点m到顶点n连通
}
//DFS递归法测试
vector<int> visited(N, 0);
//该图可能是非连通的,所有需要遍历每一个点
for (int i = 0; i < N; ++i)
{
if (visited[i])
continue;
DFS(vertex, visited, i);
}
cout << endl;
return 0;
}
三.BFS遍历
int N, C;//N个顶点,C条边
void BFS(vector<vector<int>>& vertex, vector<int>& visited, int start)
{
queue<int> que;
que.push(start);
visited[start] = 1;
while (!que.empty())
{
queue<int> tQue;
while (!que.empty())
{
int i = que.front();
que.pop();
cout << i << "->";
for (int j = 0; j < N; ++j)
{
if (0 == vertex[i][j] || visited[j])//不连通或者已经访问过
continue;
tQue.push(j);
visited[j] = 1;
}
}
swap(que, tQue);
}
}
int main()
{
cin >> N >> C;
vector<vector<int>> vertex(N, vector<int>(N, 0));
for (int i = 0; i < C; ++i)
{
int m, n;
cin >> m >> n;
vertex[m][n] = 1;//顶点m到顶点n连通
}
//从某一点开始BFS遍历
vector<int> visited(N, 0);
BFS(vertex, visited, 0);
return 0;
}