zoukankan      html  css  js  c++  java
  • 【图的遍历】广度优先遍历(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("
    ");
     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("
    
    所有探宝路径如下:
    ");
    132     findpath(G, u, v, -1, path);
    133     return 0;
    134 }

    运行结果:

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

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

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

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

    代码:

      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。

  • 相关阅读:
    第二阶段冲刺(一)
    第一冲刺阶段博客检查汇总
    整改方案
    意见
    站立会议(九)
    站立会议八
    我爱淘二次冲刺阶段1
    我爱淘冲刺阶段7
    我爱淘冲刺阶段6
    我爱淘冲刺阶段5
  • 原文地址:https://www.cnblogs.com/sunbines/p/9028903.html
Copyright © 2011-2022 走看看