笔者在前面的两篇文章中介绍了图的两种实现方法:
接下来笔者将介绍图遍历算法,与树的遍历类似,图的遍历也需要访问所有顶点一次且仅一次;此外,图遍历同时还需要访问所有的弧一次且仅一次。
图的遍历概述
图的遍历都可理解为,将非线性结构转化为半线性结构的过程。经遍历而确定的弧类型中,最重要的一类即所谓的树边,它们与所有顶点共同构成了原图的一棵支撑树(森林),称作遍历树(traversal tree)本文要介绍的BFS将是其中的一种。以遍历树为背景,其余各种类型的边,也能提供关于原图的重要信息,比如其中所含的环路等。
图中顶点之间可能存在多条通路,故为避免对顶点的重复访问,在遍历的过程中,通常还要动态地设置各顶点不同的状态,并随着遍历的进程不断地转换状态,直至最后的“访问完毕”。图的遍历更加强调对处于特定状态顶点的甄别与查找,故也称作图搜索(graph search)。
与树遍历一样,作为图算法基石的图搜索,本身也必须能够高效地实现,如深度优先、广度优先、最佳优先等基本而典型的图搜索,都可以在线性时间内完成。若顶点数和边数分别为 n 和 e,则这些算法自身仅需 0 (n + e)时间。
图的广度优先搜索概述
各种图搜索之间的区别,体现为边分类结果的不同,以及所得遍历树(森林)的结构差异。其决定因素在于,搜索过程中的每一步迭代,将依照何种策略来选取下一接受访问的顶点。
通常,都是选取某个已访问到的顶点的邻居。同一顶点所有邻居之间的优先级,在多数遍历中不必讲究。因此,实质的差异应体现在,当有多个顶点已被访问到,应该优先从谁的邻居中选取下一顶点。比如,广度优先搜索(breadth-first search, BFS)采用的策略,可概括为:越早被访问到的顶点,其邻居越优先被选用
于是,始自图中顶点s的BFS搜索,将首先访问顶点s;再依次访问s所有尚未访问到的邻居;再按后者被访问的先后次序,逐个访问它们的邻居;…&#x