【图的遍历】广度优先遍历(DFS)、深度优先遍历(BFS)及其应用

无向图满足约束条件的路径

•【目的】:掌握深度优先遍历算法在求解图路径搜索问题的应用

  【内容】:编写一个程序,设计相关算法,从无向图G中找出满足如下条件的所有路径:
  (1)给定起点u和终点v。
  (2)给定一组必经点,即输出的路径必须包含这些点。
  (3)给定一组必避点,即输出的路径必须不能包含这些点。

  【来源】:《数据结构教程(第五版)》李春葆著,图实验11。

代码:

  1 #include<stdio.h>
  2 #include<malloc.h>
  3 #define MAXV 20
  4 typedef struct ANode
  5 {
  6     int adjvex;
  7     struct ANode *nextarc;
  8 } ArcNode;
  9 
 10 typedef struct
 11 {
 12     ArcNode *adjlist[MAXV];
 13     int n1, e1;
 14 } AdjGraph;
 15 
 16 int visited[MAXV];
 17 int v1[MAXV], v2[MAXV], n, m;  // v1为必过点集合, v2为必避点集合;n为必过点的个数, m为必避点个数
 18 int count = 0; //路径个数
 19 
 20 void CreateAdj(AdjGraph *&G, int A[MAXV][MAXV], int n1, int e1)
 21 {
 22     int i, j;
 23     ArcNode *p;
 24     G = (AdjGraph*)malloc(sizeof(AdjGraph));
 25     for (i = 0; i < n1; ++i)
 26         G->adjlist[i] = NULL;
 27     for (i = 0; i < n1; ++i)
 28         for (j = n1; j >= 0; --j)
 29             if (A[i][j] == 1)
 30         {
 31             p = (ArcNode*)malloc(sizeof(ArcNode));
 32             p->adjvex = j;
 33             p->nextarc = G->adjlist[i];
 34             G->adjlist[i] = p;
 35         }
 36     G->n1 = n1;
 37     G->e1 = e1;
 38 }
 39 
 40 bool comp(int path[MAXV], int d)
 41 {
 42     int flag1 = 0, f1, flag2 = 0, f2, j;
 43     for (int i = 0; i < n; ++i)
 44     {
 45         f1 = 1;
 46         for (j = 0; j <= d; ++j)
 47             if (path[j] == v1[i])
 48             {
 49                 f1 = 0;
 50                 break;
 51             }
 52         flag1 += f1;
 53     }   
 54         
 55     for (int i = 0; i < m; ++i)
 56     {
 57         f2 = 0;
 58         for (j = 0; j <= d; ++j)
 59             if (path[j] == v2[i])
 60             {
 61                 f2 = 1;
 62                 break;
 63             }    
 64         flag2 += f2;    
 65     }    
 66     
 67     if (flag1 == 0 && flag2 == 0)
 68         return true;
 69     else
 70         return false;
 71 }
 72 
 73 void findpath(AdjGraph *G, int u, int v, int d, int path[MAXV])
 74 {
 75     int i;
 76     ArcNode *p;
 77     visited[u] = 1;
 78     ++d; path[d] = u;
 79     if (u == v && comp(path, d))
 80     {
 81         printf("路径%d:", ++count);
 82         printf("%d", path[0]);
 83         for (i = 1; i <= d; ++i)
 84             printf("->%d ", path[i]);
 85         printf("\n");
 86     }
 87     p = G->adjlist[u];
 88     while (p != NULL)
 89     {
 90         if (visited[p->adjvex] == 0)
 91             findpath(G, p->adjvex, v, d, path);
 92             p = p->nextarc;
 93     }
 94     visited[u] = 0;
 95 }
 96 
 97 int main()
 98 {
 99     AdjGraph *G;
100     int u, v; // u为起点,v为终点
101     int path[MAXV];
102     int A[MAXV][MAXV] = {
103     {0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
104     {1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0 },
105     {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
106     {1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
107     {1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
108     {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 },
109     {0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 },
110     {0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
111     {0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0 },
112     {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0 },
113     {0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0 },
114     {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0 },
115     {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1 },
116     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1 },
117     {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 } };
118     CreateAdj(G, A, 15, 21);
119     printf("输入起点和终点:");
120     scanf("%d %d", &u, &v);
121     printf("输入必过点个数: ");
122     scanf("%d", &n);
123     printf("输入必过点集合:");
124     for (int i = 0; i < n; ++i)
125         scanf("%d", &v1[i]);
126     printf("输入必避点个数: ");
127     scanf("%d", &m);
128     printf("输入必过点集合:");
129     for (int i = 0; i < m; ++i)
130         scanf("%d", &v2[i]);
131         printf("\n\n所有探宝路径如下:\n");
132     findpath(G, u, v, -1, path);
133     return 0;
134 }

运行结果:

《【图的遍历】广度优先遍历(DFS)、深度优先遍历(BFS)及其应用》

 

 

 

 

用图搜索方法求解迷宫问题

•【目的】:深入掌握图遍历算法在求解实际问题中的运用

 【内容】:编写一个程序,完成如下功能:
  (1)  建立迷宫对应的邻接表
  (2)  采用深度优先遍历算法输出从入口(1, 1)到出口(M,N)的所有迷宫路径

 【来源】:《数据结构教程(第五版)》李春葆著,图实验14。

《【图的遍历】广度优先遍历(DFS)、深度优先遍历(BFS)及其应用》

代码:

  1 #include<stdio.h>
  2 #include<malloc.h>
  3 #define MAXV  20
  4 #define N 4
  5 #define M 4
  6 typedef struct ANode
  7 {
  8     int i, j;      // i为横坐标, j为纵坐标
  9     struct ANode *nextarc;
 10 } ArcNode;
 11 
 12 typedef struct
 13 {
 14     ArcNode *mg[N + 2][M + 2];
 15 } AdjGraph;
 16 
 17 typedef struct
 18 {
 19     int i;
 20     int j;
 21 } Box;
 22 
 23 typedef struct
 24 {
 25     Box data[MAXV];
 26     int length;
 27 } Path;
 28 
 29 int visited[N + 2][M + 2] = { 0 };
 30 
 31 void CreateAdj(AdjGraph *&G, int A[N + 2][M + 2], int n, int m)
 32 {
 33     int i, j, k, i1, j1;
 34     ArcNode *p;
 35     G = (AdjGraph *)malloc(sizeof(AdjGraph));
 36     for (i = 0; i < n + 2; ++i)
 37         for (j = 0; j < m + 2; ++j)
 38             G->mg[i][j] = NULL;
 39     for (i = 1; i <= n; ++i)
 40         for (j = 1; j <= m; ++j)
 41             if (A[i][j] == 1)
 42             {
 43                 k = 1;
 44                 while (k <= 4)
 45                 {
 46                     switch (k)
 47                     {
 48                     case 1: i1 = i - 1; j1 = j; break;
 49                     case 2: i1 = i; j1 = j + 1; break;
 50                     case 3: i1 = i + 1; j1 = j; break;
 51                     case 4: i1 = i; j = j - 1; break;
 52                     }
 53                     ++k;
 54                     if (A[i1][j1] == 1)
 55                     {
 56                         p = (ArcNode*)malloc(sizeof(ArcNode));
 57                         p->i = i1;
 58                         p->j = j1;
 59                         p->nextarc = G->mg[i][j];
 60                         G->mg[i][j] = p;
 61                     }
 62                 }
 63             }
 64 }
 65 
 66 void findpath(AdjGraph *G, int x1, int y1, int xe, int ye, Path pa)
 67 {
 68     ArcNode *p;
 69     ++pa.length;
 70     pa.data[pa.length].i = x1;
 71     pa.data[pa.length].j = y1;
 72     visited[x1][y1] = 1;
 73     if (xe == x1 && ye == y1)
 74     {
 75         for (int u = 0; u <= pa.length; ++u)
 76             printf(" (%d, %d) ", pa.data[u].i, pa.data[u].j);
 77     }
 78 
 79     p = G->mg[x1][y1];
 80     while (p != NULL)
 81     {
 82 
 83         if (visited[p->i][p->j] == 0)
 84             findpath(G, p->i, p->j, N, M, pa);
 85         p = p->nextarc;
 86     }
 87     visited[x1][y1] = 0;
 88 }
 89 
 90 int main()
 91 {
 92     AdjGraph *G;
 93     Path pa;
 94     int A[N + 2][M + 2] = {
 95         { 0, 0, 0, 0, 0, 0 },{ 0, 1, 1, 1, 0, 0 },
 96     { 0, 1, 0, 1, 1, 0 },{ 0, 1, 1, 1, 0, 0 },
 97     { 0, 0, 1, 1, 1, 0 },{ 0, 0, 0, 0, 0, 0 } };
 98     CreateAdj(G, A, N, M);
 99     pa.length = -1;
100     findpath(G, 1, 1, N, M, pa);
101     return 0;
102 }

 

 

 

 求解两个动物之间通信最少翻译问题

•【目的】:掌握广度优先遍历算法在求解实际问题中的运用

 【内容】:编写一个程序,完成如下功能:
据美国动物分类学家欧内斯特-迈尔推算,世界上有超过100万种动物,各种动物有自己的语言。假设动物A只能与动物B通信,所以,动物A、C之间通信需要动物B来当翻译。问两个动物之间项目通信至少需要多少个翻译。
     测试文本文件test.txt中第一行包含两个整数n(2<= n <= 200)、m(1 <= m <= 300),其中n代表动物的数量,动物编号从0开始,n个动物编号为0 ~ n-1,m表示可以相互通信动物数,接下来的m行中包含两个数字分别代表两种动物可以相互通信,在接下来包含一个整数k(k <= 20),代表查询的数量,每个查询,输出这两个动物彼此同喜至少需要多少个翻译,若它们之间无法通过翻译来通信,输出-1.

输入样本      输出结果
3 2                 0
0 1                 1             
2
0 0
0 2

 【来源】:《数据结构教程(第五版)》李春葆著,图实验12。

    原文作者:苏格拉底的落泪
    原文地址: https://www.cnblogs.com/sunbines/p/9028903.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞