其实说到数据结构的学习,遍历这个词出现的频率是非常非常高的,我们要操作每个数据就必须访问它。图也不例外,图的遍历方式主要有两种,一个是深度优先搜索(deep first search),一个是广度优先搜索(broad first search)。
首先是两种遍历的具体思路:对于深度优先搜索,给出一个出发点,这个出发点有许多邻接点,可以构成许多的路径。深度优先就是逮住一条路径先走到黑,黑了之后回到之前的起点,然后找一个没走过的点继续这个过程,全走黑之后就遍历完成了。整个遍历的过程通过递归的方式完成,具体的python代码如下:
def deep_first(mat,n,visited,start):
visited[start] = 1
print(start)
for i in range(n):
if start>i:
pos = i+(start*(start+1))/2
else:
pos = start+(i*(i+1))/2
if mat[int(pos)] == 1 and visited[i] != 1:
deep_first(mat,n,visited,i)
这里用print表示访问过某个点,用visited这个一维数组表示是否访问过某个点,pos代表某个点在邻接矩阵中的位置。如果第i点和start相连并且还没被访问过,那么就以该点为下一个起点进行深度优先搜索。
可以看出来,这个遍历是一个单源的遍历,并且是在一个连通图里进行的。它的一个很重要的特性就是一路走到黑,做题的时候其实颇有点投机的味道在里面。
然后是广度优先搜索,这个遍历方法和二叉树里的层序遍历极为相似。也可以说树就是图的一种比较特殊的情况。思路就是层层扩散,一层一层的向外遍历。具体的python代码如下:
def broad_first(mat,start,n,visited):
que = []
visited[start] = 1
que.insert(0,start)
while que!=[]:
k = que.pop()
print(k)
for i in range(n):
if k > i:
pos = i+(k*(k+1))/2
else:
pos = k+(i*(i+1))/2
if mat[int(pos)] == 1 and visited[i] != 1:
que.insert(0,i)
visited[i] = 1
借助一个que队列,一开始先让起点进队,然后进入while循环,把排头出队,然后把他的所有邻接点中未被访问的节点进队并改变对应的visited的值,重复这个过程即可完成遍历。n为节点的个数。
假设有一个图,图的正中央是起点,广度优先搜索就有种把石头扔进水里的感觉,水波层层扩散开来。
具体两种遍历方式的利弊其实主要取决于图是什么样的,比如说我走迷宫,如果出口离入口很远,那么显然深度优先搜索要更好一些。具体问题具体分析。