恰巧离散数学学到了图的矩阵表示(最后一节了),复习一下图的遍历方式吧,没想到网课上到了将近结课
一、举例分析
深度优先搜索(DFS)是一种顺序搜索,一条路走到黑,直到搜索无法进行,回退到上一个可继续搜索的点,逐渐遍历全图。
广度优先搜索(BFS)将图分离为层,每层之间间隔一步,每个点被遍历的次序和遍历该图的初始点的距离有关。
如该图例子1,按照深度优先搜索从点1开始遍历:
- 1–>2–>4,无法继续搜索,回退一步到点2
- 2–>5,无法继续搜索,回退一步到点2
- 仍然无法继续,再回退一步到起点1
- 1–>3,已搜索完全部点,搜索结束
- 遍历顺序为1–>2–>4–>5–>3,总结就是一条路走到黑,然后回头走这条路上的分支
按照广度优先搜索从点1开始遍历:
- 点1可以到达点2和点3,当前已遍历1–>2–>3
- 点2可以到达点4和点5,当前已遍历1–>2–>3–>4–>5;点3无法继续
- 点4和点5均无法继续,搜索结束,遍历顺序为1–>2–>3–>4–>5
- 总结就是将图分为层,每次通过该层的点确定下一层的点,如此直到搜索到最后一层
再举个例子2,分析一下广度优先搜索
深度优先搜索该图,一条路走到黑刚好遍历完全,1–>2–>3–>4–>5–>6–>7–>8
按照广度优先搜索,从点1开始遍历:
- 点1可以到达2,当前已遍历1–>2
- 点2可到达点3和点7,当前已遍历1–>2–>3–>7
- 点3可到达点4,当前已遍历1–>2–>3–>7–>4;点7可到达点5和点6,当前已遍历1–>2–>3–>7–>4–>5–>6
- 点4、点5和点6均不符合继续搜索的条件,搜索结束,遍历顺序为1–>2–>3–>7–>4–>5–>6
- 这就是把图分为了4层({1},{2},{3,7},{4,5,6}),由上一层确定下一层的点,不重复遍历
二、写成代码
用邻接矩阵表示图,
1.深度优先
可以用递归模拟一条路走到黑,走到黑屋后return返回到上一个仍可继续搜索的地方
#include <iostream>
#include <stdio.h>
#include <string>
#include <algorithm>
using namespace std;
int My_Map[21][21] = { 0 }, book[21] = { 0 };//book标记,0该店未遍历,1已遍历
int n, sum = 0;
void dfs(int step) {//当前处于编号为step的点
cout << step << " ";
sum++;
if (sum == n) return;//已遍历完所有点
for (int i = 1; i <= n; i++) {
if (My_Map[step][i] == 1 && book[i] == 0) {
book[i] = 1;
dfs(i);//继续走,直到黑屋再回来
}
}
return;
}
int main() {
cout << "输入邻接矩阵行列数:";
cin >> n;
cout << "输入邻接矩阵:" << endl;
for (int a = 1; a <= n; a++) {
for (int b = 1; b <= n; b++) {
cin >> My_Map[a][b];
}
}
book[1] = 1;
cout << "DFS遍历顺序为:";
dfs(1);
return 0;
}
例1的测试:
2.广度优先
根据上一层的点确定下层的点,且越早找到的点被用来作为确定下一层点的时机越早,利用队列先进先出的特性
#include <iostream>
#include <stdio.h>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;
int main() {
int n;
cout << "输入邻接矩阵行列数:";
cin >> n;
cout << "输入邻接矩阵:" << endl;
int My_Map[21][21], book[21] = { 0 };
for (int a = 1; a <= n; a++) {
for (int b = 1; b <= n; b++) {
cin >> My_Map[a][b];
}
}
queue<int> que;//队列中存储待遍历的点
que.push(1);//从1号开始遍历
book[1] = 1;
cout << "BFS遍历顺序为:";
while (!que.empty()) {
cout << que.front() << " ";
for (int i = 1; i <= n; i++) {
if (My_Map[que.front()][i] == 1 && book[i] == 0) {
que.push(i);
book[i] = 1;
}
}
que.pop();
}
cout << endl;
return 0;
}
例2的测试:
其实这两个图是我在离散的课本上随便抠出来的(lll¬ω¬)