搜索和遍历在图中有何区别和联系?

 我们都知道有深度/广度优先搜索 和 深度/广度优先遍历,而且都称其为DFS和BFS,

那么他们在图的算法中有什么区别呢?如果没区别那肯定不会是不同的部分吧~

这篇文章就给出我的一些理解

问题的提出

今天在看算法笔记时注意到书上写的遍历方法,在枚举“方向”时,用的是这样的方式

for(int v = 0; v < n; v++){

        if(vis[v] == false && G[u][v] != INF){

                q.push(v);

                vis[v] = true;

        }

}

但是在搜索方法的时候,却是这样的写法 (例如马的遍历这一题)

for(int i = 0;i<8;i++){

        nx=f.xx+Next[i][0]; ny=f.yy+Next[i][1]; step=f.steps+1;

        if(book[nx][ny]==0 && nx>=1 && nx<=n && ny>=1 && ny<=m){

                qipan New;

                New.xx=nx; New.yy=ny; New.steps=step;

                q.push(New);  book[nx][ny]=1; ans[nx][ny] = step;

        }

}

首先,最明显的不同就是“方向”,在搜索时,是从4或8...个固定(上下左右)的方向进行枚举

而在遍历时,只是通过存储的图中的边进行依次枚举。

这让我不禁思考一下,为什么不同了,又或者能互换这样的枚举方式吗?

问题的讨论

对于这样的一个“学术执着”精神,必须给它想清楚了心里才觉得踏实,于是我沉思许久。

一开始,我感觉到,是因为他们需要的枚举方向不同,所以遍历是从一个点依次判断。

但是这样都是枚举方向,为什么一个这样,另一个那样?

搜索的时候,如果也用G[u][v]来进行DFS、BFS可以吗?

遍历的时候,如果也用NEXT[][]数组来保存方向可以吗?

想了半天好像感觉不可以。为什么不可以呢?

想通了发现,按道理是可以的,因为同样是图,所以本质是不变的,况且他们的深度优先和广度优先的思想是不变的

但是!在图的搜索当中,我们一般是给的具体一个“图”,而图的遍历当中,我们给的是点与点之间的连接关系,所以就造成了差异!

这一点从具体的算法题也可以非常之明显地看出来!

例如:

搜索给出的数据是这样的

0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1

什么意思呢?这就相当于给了具体的地图是长什么样~ 也就是说,已经是形象地表现出来了地图,

从而四个(或多个)方向的枚举就是上下左右这样的方向,因此我们在搜索时是利用一个next[4][2]

这样的一个二维数组来记录方向,通过队首的坐标加以计算方向进行枚举

同时也可以看出:搜索 沿着某个路径访问

遍历给出的数据是这样的

4 3
1 2
2 4
4 3

 什么意思呢?相当于只给了你点与点之间的一些连接的关系,表示是否连通,这样的地图是抽象概念的,并非像搜索一样给出的是“图的样子”

所以我们在遍历一个顶点的时候,是根据这个顶点于其相连接的边来依次枚举

同时也可以看出:遍历 是线性访问

总结一下

搜索: 二维数组中存放的是 具体的地图 通过计算方向进行枚举

遍历:二维数组中存放的是 抽象的地图 根据边的存在进行枚举

而就其它而言,它们都算图论算法,并且深度优先和广度优先的思想是一样的,

只不过在枚举的时候有不同的方式,

并且搜索不仅用于图,还能用于很多其他非图的算法~~~

以上是本人阅读《算法笔记》之后产生的一些感悟,若有错误和不足,还请读者在评论区或私信留言,大家一起学习,共同进步。

学好程序和算法,走遍天下都不怕。

猜你喜欢

转载自blog.csdn.net/weixin_44572229/article/details/121423748
今日推荐