数据结构回顾与总结 图(2)两种基本的遍历方式

来源:互联网 发布:canvas2image.js 下载 编辑:程序博客网 时间:2024/05/22 01:22

其实说到数据结构的学习,遍历这个词出现的频率是非常非常高的,我们要操作每个数据就必须访问它。图也不例外,图的遍历方式主要有两种,一个是深度优先搜索(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为节点的个数。

假设有一个图,图的正中央是起点,广度优先搜索就有种把石头扔进水里的感觉,水波层层扩散开来。

具体两种遍历方式的利弊其实主要取决于图是什么样的,比如说我走迷宫,如果出口离入口很远,那么显然深度优先搜索要更好一些。具体问题具体分析。