分别用DFS和BFS实现图的遍历
DFS模板:
1
2
3
4
5
6
7
8
9
10
111 void dfs(int step) {
2 if (...) //判断边界,到达边界则返回
3 return;
4 for (循环所有方向) {
5 if (...) { //可能需要判断条件
6 book[...] = 1; //标记
7 dfs(step+1);
8 book[...] = 0; //取消标记
9 }
10 }
11 }用DPS遍历图。我们用一个二维数组e来储存图。
我们用上面二维数组中的(i, j)储存的数字来表示顶点i到顶点j是否有边——1表示有边,∞表示没有边,0表示自己到自己(即i等于j)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
431 //图的遍历 - 深度优先
2 #include <stdio.h>
3 int book[101], sum, n, e[101][101];
4
5 void dfs(int cur) { //cur是当前所在的顶点编号
6 int i;
7 printf("%d ", cur);
8 sum++; //每访问一个点,sum就加1
9 if (sum == n) return; //所有的顶点都已经访问过则直接退出
10 for (i = 1; i <= n; i++) { //从1号顶点n号顶点依次尝试,看哪些顶点与当前顶点cur有边相连
11 //判断当前顶点cur到顶点i是否有边,并判断顶点i是否已访问过
12 if (e[cur][i] == 1 && book[i] == 0) {
13 book[i] = 1; //标记顶点i已经访问过
14 dfs(i); //从顶点i再出发继续遍历
15 }
16 }
17 return;
18 }
19
20 int main() {
21 int i, j, m, a, b;
22 scanf("%d %d", &n, &m);
23 //初始化二维矩阵
24 for (i = 1; i <= n; i++)
25 for (j = 1; j <= n; j++)
26 if (i == j)
27 e[i][j] = 0;
28 else
29 e[i][j] = 99999999; //我们这里假设99999999为正无穷
30
31 //读入顶点之间的边
32 for (i = 1; i <= m; i++) {
33 scanf("%d %d", &a, &b);
34 e[a][b] = 1;
35 e[b][a] = 1; //这里是无向图,所以需要将e[b][a]也赋为1
36 }
37
38 //从1号顶点出发
39 book[1] = 1; //标记1号顶点已访问
40 dfs(1); //从1号顶点开始遍历
41
42 return 0;
43 }
结果如下:
BFS模板:
1
2
3
4
5
6
7
8
9
10
111 while (head < tail) {
2 for(循环所有方向) {
3 if (可能需要判断条件) {
4 ... //更新当前坐标
5 if (...) continue; //判断所有不可能的情况,不可能就continue
6 book[...] = 1; //标记
7 tail++;
8 }
9 }
10 head++;
11 }用BFS遍历图:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
531 //图的遍历 - 广度优先
2 #include <stdio.h>
3
4 int main() {
5 int i, j, n, m, a, b, cur, book[101] = {0}, e[101][101];
6 int que[10001], head, tail;
7 scanf("%d %d", &n, &m);
8 //初始化二维矩阵
9 for (i = 1; i <= n; i++)
10 for (j = 1; j <= n; j++)
11 if (i == j)
12 e[i][j] = 0;
13 else
14 e[i][j] = 99999999;
15
16 //读入顶点之间的边
17 for (i = 1; i <= m; i++) {
18 scanf("%d %d", &a, &b);
19 e[a][b] = 1;
20 e[b][a] = 1;
21 }
22
23 //队列初始化
24 head = 1;
25 tail = 1;
26
27 //从1号顶点出发,将1号顶点加入队列
28 que[tail] = 1;
29 tail++;
30 book[1] = 1; //标记1号顶点已访问
31
32 //当队列不为空时,循环
33 while (head < tail) {
34 cur = que[head]; //当前正在访问的顶点编号
35 for (i = 1; i <= n; i++) { //从1~n依次尝试
36 //判断从顶点cur到顶点i有边,并且顶点i没有被访问过,则将顶点i入队
37 if (e[cur][i] == 1 && book[i] == 0) {
38 que[tail] = i;
39 tail++;
40 book[i] = 1; //标记顶点i已访问
41 }
42 //如果tail大于n,则表明所有顶点都已经被访问过
43 if (tail > n) {
44 break;
45 }
46 head++; //不要忘记,一个顶点扩展结束后,head++,然后才能继续往下扩展
47 }
48
49 for (i = 1; i < tail; i++)
50 printf("%d ", que[i]);
51 return 0;
52 }
53 }结果如下:
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 怀民亦未寝。!