一个问题
我们都知道在很多学校,有着许多的修学科目,但是这些科目却要有先后关系。比如,你要先学习**高等数学**,才可以报**计算机科学**等
现在有一个人把报名学科的先后条件给你,让你找一个合理的方案,使得能够按你的顺序一次性学完整个任务
什么意思
意思是,有很多科目都有先修课程,你要先学完那个先修课程,才可以学这个课程;当然,那个先修课程可能还有自己的先修课程
怎么解决
很多人都知道,我们需要先找到第一个可以学的科目,等到学完以后再看看有没有学科可以学了,以此类推,直到学完为止
那么,这种算法,叫做拓扑排序 (topsort)
——————————————分割线————————————————
什么是拓扑排序
在一个有向无环图里面,每一个点有入边或出边,问怎样才可以标记到一个点时,它的前驱全部都标记过
最终按照这种顺序排列下来的一条线性表,就是拓扑序列
拓扑排序算法
就像我们上面的例子,你要先把先修学科全部学完,才可以学这一个科目
那我们应该怎么样才能找到第一个可以学习的学科呢?
肯定是找到一个没有先修课程的学科吧
那么,拓扑排序也是一样的,如果这个点的入度为 0,那么代表着这个点**没有前驱**,所以可以直接标记
那么,学完了这个科目,所有以这个科目为先修课的科目均可以进行学习
所以在算法中,每次标记结束后,要删除连接它的所有出边
当然,剩余的点的入度也要随着边的删除而改变
下面给出一个例子
3 3 //三个顶点、三条边 3 1 //一的前驱为三 1 2 //二的前驱为一 3 2 //二的前驱为三
第一步,确定每个点的入度
一号点入度为 1,二号点为 2,三号点为 0
第二步,从三号点开始
标记三号点,因为从三号点分别有一条通向一号点、二号点的边,所以把一号、二号点的入度分别减一
第三步,检查每个点入度
发现一号点入度为 0 ,所以把一号点进行标记
因为有一条一号点到二号点的边,所以二号点的入度减一
第四步,继续检查每一个点入度
发现只有二号点了,所以标记二号点,排序结束
所以,最终答案是 3--1--2