BFS与DFS两种视角下的拓扑排序

  拓扑排序一般用来解决求一个有先后关系的排序问题。如果在一连串事件中,有着必要的先后关系或依赖关系,就可以抽象成图中的拓扑排序。

出度和入度

  拓扑排序需要用到出度和入度的概念。

  出度:以该点为起点的边的数量

  入度:以该点为终点的边的数量

  如果把图中每个结点看作一个事件,边看作一种依赖关系。那么一个点的入度就是该点所需的先决条件数量,一个点的出度就是 以该点作为其他点先决条件 的 点的数量。显然,入度为0的点,就是序列的起始点。

显然,一个图可以进行拓扑排序的充要条件是他是一个有向无环图(DAG)

BFS进行拓扑排序

  bfs下的拓扑排序有两种思路:

  • 无前驱优先型
  • 无后继优先型

  无前驱优先型的算法思路是:先找出图中入度为0的点(没有前驱)加入队列,然后将该点所有的后继点的入度减一(相当与把加入队列的点从图中删除)。

然后重复这一步骤,直到所有点加入队列,则完成拓扑排序。

  无后继优先型的思路与无前驱型相同,不过在队列中的结点顺序的逆序才是它的拓扑排序。

  无法完成拓扑排序(不是DAG)的情况:如果图中不存在入度(或出度)为0的点,但仍有点未加入队列,证明它不是一个有向无环图,没有拓扑排序。

DFS进行拓扑排序

  dfs天然适合拓扑排序,因为它的访问过程本身就需要(在一定程度上)按照拓扑排序。

  具体思路就是,先找到一个入度为0的点,对其进行dfs,回溯时的顺序就是就是拓扑排序的逆序。

  有以下几个要注意的点:

  1. 每次访问的结点必须入度为零
  2. 不能出现回退边(访问到一个在前边的递归过程中没有处理完的点),出现回退边意味着这个图不是一个有向无环图

按最小的字典序输出拓扑排序

  一个图的拓扑排序往往不只有一种,所以有时题目要求输出字典序最小的拓扑排序,这时我们只需要把bfs中的队列换成优先队列就好,同时入度为0的点字典序小的先出队。

  (这时不能用dfs的方法,因为dfs是按层搜索,无法区分同一层结点的优先级)

几道练手水题

  to be continued......

posted @ 2020-11-26 15:35  HUIZIXUAN  阅读(631)  评论(0)    收藏  举报