算法描述
关于深度优先遍历(DFS)和广度优先遍历(BFS)的遍历方式大体一致:
-
选择某一个顶点作为起始点 —— 函数xxxTraverse()
-
若改点未被访问过,即visit[i]=0时,则将其放入栈/队列
-
当栈/队列不为空时,弹出top(栈)/front(队列)元素,并判断其是否被访问过
-
如果没有则输出,并将其状态改为已访问,即visit[i]=1,之后对该元素的邻居进行循环遍历(for)
-
重新返回Step.2,直到栈/队列为空,完成遍历
DFS代码实现
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<stack>
using namespace std;
class Graph
{
bool* visit;
int** adjMatrix;
int vernum;
//stack<int>*s;
public:
Graph()
{
cin >> vernum;
adjMatrix = new int* [vernum];
visit = new bool[vernum];
//s = new stack<int>[vernum];
for (int i = 0; i < vernum; i++)
{
adjMatrix[i] = new int[vernum];
visit[i] = false;
for (int j = 0; j < vernum; j++)
{
cin >> adjMatrix[i][j];
}
}
}
~Graph()
{
for (int i = 0; i < vernum; i++)
{
delete[]adjMatrix[i];
}
delete[]adjMatrix;
delete[]visit;
}
//递归——除了用栈,递归也是一种解决方法,不过由于复杂度问题,一般更推荐使用栈
//void DFS(int i)
//{
// cout << i << " ";
// visit[i] = true;
// for (int j = 0; j < vernum; j++)
// {
// if (adjMatrix[i][j] && !visit[j])DFS(j);
// }
//}
//void DFSTraverse()//从顶点开始遍历
//{
// for (int i = 0; i < vernum; i++)
// {
// if (!visit[i])DFS(i);
// }
// cout << endl;
//}
//栈实现
void DFS_iter(int i)
{
s->push(i);
while (s->size() > 0)
{
i = s->top();
s->pop();
if (!visit[i])
{
cout << i << " ";
visit[i] = true;
for (int j = 0; j < vernum; j++)
{
if (adjMatrix[i][j]&&!visit[j])s->push(j);
}
}
}
}
void DFS_iterTraverse()
{
for (int i = 0; i < vernum; i++)
{
if (!visit[i])DFS_iter(i);
}
}
};
int main()
{
int t;
Graph g;
g.DFS_iterTraverse();
}
BFS代码实现
#include<iostream>
#include<queue>
using namespace std;
class Graph
{
bool* visit;
int** adjMatrix;
int verNum;
queue<int>* q;
public:
Graph()
{
cin >> verNum;
visit = new bool[verNum];
adjMatrix = new int* [verNum];
q = new queue<int>[verNum];
for (int i = 0; i < verNum; i++)
{
adjMatrix[i] = new int[verNum];
visit[i] = false;
for (int j = 0; j < verNum; j++)
{
cin >> adjMatrix[i][j];
}
}
}
~Graph()
{
for (int i = 0; i < verNum; i++)
{
delete[]adjMatrix[i];
}
delete[]visit;
delete[]adjMatrix;
}
void BFS_Traverse()
{
for (int i = 0; i < verNum; i++)
{
if (!visit[i])BFS(i);
}
}
void BFS(int i)
{
q->push(i);
while (q->size() > 0)
{
i = q->front();
q->pop();
if (!visit[i])
{
cout << i << " ";
visit[i] = true;
for (int j = 0; j < verNum; j++)
{
if (!visit[j] && adjMatrix[i][j])q->push(j);
}
}
}
}
};
int main()
{
Graph g;
g.BFS_Traverse();
}
碎碎念
我一开始学这两个遍历时,总是搞不懂里面的逻辑:为什么一个用栈,而另一个用队列?为什么要创建visit数组?怎样才能访问顶点的邻居......后面静下心来,找了几个视频看,并跟着里面的伪代码编写可运行代码,总算摸索出一点门道来。所以当遇到问题时,不要想着逃避,或许静下心来思考,或许能擦出点火花~ 若有不足,欢迎指出~