利用深度优先搜索进行图的遍历

显然,图分为两种:无向图有向图

无向图示例:
在这里插入图片描述
如图,任意两个相连的结点是可以互相通达的。例如,V1与V2相连,那么从V1可以到达V2,从V2也可以到达V1(所有路径都是双向的).

有向图示例:
在这里插入图片描述
对于任意两个相连的结点U、V,若存在存在从U到V的路径,即不存在从V到U的路径(所有路径都是单向的)。

在利用邻接矩阵描述图的情况下,我接下来阐释如何利用深度优先搜索进行两种图的遍历。

无向图的深度优先遍历

在这里插入图片描述

无向图–>表格

对于如上的无向图,我们可以用如下的表格进行描述。
最左列的黑色数字表示出发点,最上行的黑色数字表示终止点,红色1表示有路径。
在这里插入图片描述

表格–>数组(类似于邻接矩阵)

如果用二维数组map[7][7]描述该表格,设定出发点为一维坐标终止点为二维坐标,那map[ i ][ j ](1<=i<=6,1<=j<=6)为
在这里插入图片描述0表示没有路径,1表示有路径。
map[ 1 ][ 2 ]==1 <=>结点1 可通向结点2 ,
map[ 2 ][ 1 ]==1 <=>结点2 可通向结点1.

实例分析

假设从结点1出发遍历整个如上的无向图,

1、 搜索结点1的每条路径(有多少出度)。如上图,结点1有3条路径(出度)(1—2、1—3、1—3)。
2、沿结点 1的3条路径逐一深入搜索,直到不能继续前进为止(在搜索的过程中要将探访过的所有结点一一标记,防止重复搜索)。所谓不能继续前进有两种情况:

(1). 当前结点已访问过
(2). 当前结点已无未被访问过的路径
3、先讨论1—2路径。结点2的两条路径中,2—1路径已经访问过,所以只需访问2—5路径。
(红色区域意为已经访问过,绿色三角形为当前搜索进度)
在这里插入图片描述
结点5的三条路径中5—2已访问过,所以接下来分别访问5—3、5—6。
(1)5—3路径。结点3的3条路径中3—5、3—1已访问过,所以接下来分别访问3—4、3—6路径。
在这里插入图片描述
①3—4路径。结点4的三条路径中4–1、4—3已经访问过,所以只能探访4—6路径。
在这里插入图片描述
结点6的所有路径都访问过,已无法前进
②3—6路径。结点6已访问过,无法前进
(2)、5–6路径中的结点6已访问过,无法前进
4、1—3路径中结点3已访问过,无法前进
5、1—4路径中结点4已访问过,无法前进
搜索结束……

思路概括

  1. 任选一个结点作为出发点,以此结点为中心,逐一探访该结点 的所有路径(路径1、路径2、……、路径n)。途中每到达新的结点,则又以此新结点为中心,逐一探访该结点 的所有路径(路径1‘、路径2’、……、路径n’)。(是不是该用递归呢……)
  2. 每到一个结点就检查该结点是否被访问过以及是否有未被访问的路径。两者之中只要一个为是,则停止对本条路径的搜索。

代码示例

#include <stdio.h>
#include <stdlib.h>

int n,m;//n代表路径数量,m为结点数量
int map[100][100];
int visit[100];//visit用于标记结点

int DFS(int number)//number结点编号
{
    int i;
    if(visit[number])//该结点已被访问过
    {
        return 0;//结束搜索
    }
    printf("%d ",number);//打印结点
    visit[number]=1;//标记结点
    for(i=1;i<=m;i++)//探访当前结点的所有可能的相邻路径
    {
        if(map[number][i])//若有通向其它结点的路径
        {
            DFS(i);//沿路径深入搜索
        }
    }
    return 0;
}

int main()
{
    int start;//出发点
    int i,start_point,end_point;//start_point路径起始点,end_point路径终止点
    printf("Please input the number of paths and number of nodes\n");
    scanf("%d%d",&n,&m);//输入路径数量和结点数量
    printf("Please input the start_point and end_point\n");
    for(i=1;i<=n;i++)
    {
        scanf("%d%d",&start_point,&end_point);
        //因为是无向图,所以路径是对称的
        map[start_point][end_point]=1;
        map[end_point][start_point]=1;
    }
    printf("Please input the start\n");
    scanf("%d",&start);
    if(start>n||n==0)
    {
        return 0;
    }
    else
    {
        DFS(start);
    }
    return 0;
}

有向图的深度优先遍历

有向图的深度优先遍历思路与无向图基本相同,唯一不同的是,因为有向图的路径是非对称的(即对于任意两个相连的结点U、V,若存在存在从U到V的路径,即不存在从V到U的路径),所以在构造邻接矩阵时部分元素不需要被赋1.

for(i=1;i<=n;i++)
    {
        scanf("%d%d",&start_point,&end_point);
        //因为是有向图,所以路径是非对称的
        map[start_point][end_point]=1;
    }

不当之处,敬请斧正……

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值