码迷,mamicode.com
首页 > 编程语言 > 详细

拓扑排序

时间:2017-05-20 13:13:52      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:nbsp   操作   ddd   访问   程序设计   解法   out   bbb   next   

概述

对一个 有向无环图(Directed Acyclic Graph, DAG) G 进行拓扑排序,是将 G 中的所有顶点排成一个线性序列,

使得图中任意一对顶点 u 和 v,若边 <u,v>E(G),则 u 在线性序列中出现在 v 之前。

通常,这样的线性序列称为满足拓扑次序(Topological Order) 的序列,简称 拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为 拓扑排序。

技术分享

例如,在计蒜客平台上选择软件工程方向,我们会给出一个专业方案列表,如上图。

你需要根据专业方案学习列表上的必修课程和选修课程,而学习每门课程的先决条件是学习完它的全部先修课程。

如学习《数据结构》课程就必须安排在它的先修课程《离散结构》之后。

而学习《C 语言程序设计》课程可以随时安排,因为它是基础课程,没有先修课。

一个符合要求的学习课程的顺序就是对这些课程进行拓扑排序。

 

算法流程

拓扑排序算法主要由以下两步循环执行,直到不存在入度为 0 的顶点为止。

  1. 选择一个入度为 0 的顶点并将它输出;
  2. 删除图中从顶点连出的所有边。

循环结束,若输出的顶点数小于图中的顶点数,则表示该图中存在回路,也就是无法进行拓扑排序;否则输出的顶点序列就是一个拓扑序列。

接下来,我们用一个例子来说明这个算法过程。

对于如下的图,我们首先算出所有顶点的入度,并找出其中所有入度为零的顶点,发现只有 0,于是我们将 0 插入队列中。

图中圆圈内的数字表示顶点的入度,圆圈下方的数字表示顶点编号,直线表示边,直线一端的箭头表示边的方向。

图的下方是一个队列,用来在拓扑排序时储存所有未处理的入度为零的顶点。

技术分享

枚举 0 连出的所有边,对于每条边,将另一端的顶点的入度减一。发现有新的入度为零的点 2,则将它们都插入到队列中。

技术分享

处理完成后将队首元素出队,继续访问当前的队首元素 2。

技术分享

枚举 2 连出的所有边,对于每条边,将另一端的顶点的入度减一。这时发现顶点 1 和顶点 4 的入度均为零,将它们都插入队列。

技术分享

处理完成后将队首元素出队,继续访问当前的队首元素 1。

技术分享

枚举 1 连出的所有边,修改对应的入度。

技术分享

将 1 出队,继续访问当前的队首元素 4,调整对应顶点的入度。发现顶点 3 的入度为零,将它插入队列中。

技术分享

将 4 出队,目前队首顶点为 3,发现没有和它相邻的顶点,将其出队。此时队列为空,算法结束。

我们发现,这 5 个顶点已经都访问过了,所以最终顶点入队的顺序就是这张有向图的一个拓扑排序。

技术分享

拓扑排序

标签:nbsp   操作   ddd   访问   程序设计   解法   out   bbb   next   

原文地址:http://www.cnblogs.com/wangkaipeng/p/6881911.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!