6.4.6拓扑排序

6.4.6拓扑排序_第1张图片

 用DAG(有向无环图)表示一个工程。顶点表示活动,有向边表示活动Vi活动必须先与Vj活动进行。

6.4.6拓扑排序_第2张图片

 所谓的拓扑排序:找到做事的先后顺序

6.4.6拓扑排序_第3张图片

 6.4.6拓扑排序_第4张图片

 6.4.6拓扑排序_第5张图片

 6.4.6拓扑排序_第6张图片

 6.4.6拓扑排序_第7张图片

 6.4.6拓扑排序_第8张图片

 6.4.6拓扑排序_第9张图片

以上根据拓扑排序的实现:6.4.6拓扑排序_第10张图片

加入对有回路的图进行拓扑排序:

6.4.6拓扑排序_第11张图片

 所以原图如果存在回路,就不存在拓扑排序。

6.4.6拓扑排序_第12张图片

 采用邻接表进行存储

定义了一个indegree[]数组

6.4.6拓扑排序_第13张图片

定义一个print数组(刚开始全部初始化为-1)

6.4.6拓扑排序_第14张图片

一个空栈S

6.4.6拓扑排序_第15张图片

 6.4.6拓扑排序_第16张图片

 检查indegree数组当前入度为0的顶点

6.4.6拓扑排序_第17张图片

 6.4.6拓扑排序_第18张图片

将与2号结点相连的结点的入度减去1.

 6.4.6拓扑排序_第19张图片

 接下来我们处理入度为0的还有0号结点。

在while循环里面处理和0号结点相连的几个节点。

接着是1号结点的入度因为减去1之后变成了0。

6.4.6拓扑排序_第20张图片

 此时将1号结点也压入栈中

6.4.6拓扑排序_第21张图片

 接着把3号结点和4号结点也压入栈中。

6.4.6拓扑排序_第22张图片

 

下面我们来认识一下逆拓扑排序:

出栈的时候出出度为0
6.4.6拓扑排序_第23张图片

 6.4.6拓扑排序_第24张图片

 随便删除切番茄和打鸡蛋

6.4.6拓扑排序_第25张图片

 6.4.6拓扑排序_第26张图片

 6.4.6拓扑排序_第27张图片

 我么在删除出度为0的顶点时,还需要删除对应的边,就需要将邻接表全部遍历一遍去寻找其前驱。

6.4.6拓扑排序_第28张图片

 所以最好使用邻接矩阵去存储(这样就可以直接去第5列的值)

发现它的前驱是2和3.

也可以采用逆邻接表去存储

我们也可以用DFS算法实现拓扑排序

6.4.6拓扑排序_第29张图片

 6.4.6拓扑排序_第30张图片

 6.4.6拓扑排序_第31张图片

 6.4.6拓扑排序_第32张图片

 6.4.6拓扑排序_第33张图片

 接下来我们会把4打印输出:

6.4.6拓扑排序_第34张图片

 对于3号节点来说,也找不到一个与之相邻且未被访问过的结点。

6.4.6拓扑排序_第35张图片

 6.4.6拓扑排序_第36张图片

 6.4.6拓扑排序_第37张图片

 6.4.6拓扑排序_第38张图片

 我们的函数会重新回到上面这个for循环,寻找visited数组为False的顶点。

6.4.6拓扑排序_第39张图片

 随意我们发现使用DFS算法,顶点在推出递归栈之前会输出成逆拓扑排序失败

6.4.6拓扑排序_第40张图片

 

你可能感兴趣的:(数据结构,考研)