一、有向无环图
- 有方向
- 没有闭环
二、拓扑排序
拓扑排序是将有向无环图的顶点排成一个线性序列的过程。
比如可将上图
三、拓扑排序步骤
1. 首先要任意选择一个没有前驱的顶点,即入度为0的点,然后将它输出。
在下面这张图中我们选择1为出发点。
2. 删除该节点以及与它相关联的所有边,这个点的nexts里面的点入度就减少1
选择1为出发点之后,我们将它输出,并删除该节点以及与它相关联的所有边。
3. 然后在删除后的图中继续找一个没有前驱的节点,
这里没有前驱的节点只有2和3.
这里我们选择3,那么将节点3输出后的图 如下图所示。
4. 继续找入度为0的点重复上述步骤。
接下来没有前驱的节点只有2和6了。
我们这里选择节点6,同样的输出节点6后删除。
然后继续找没有前驱的节点。这时候没有前驱的节点只剩下节点2.
接下来的点继续进行拓扑排序,
5. 得到的拓扑排序的一种如下图所示。
相信大家也都发现其实拓扑排序是不唯一的,我们选择的出发点不同,结果就是不一样的。
这里给出大家针对上图几种拓扑排序序列。
四、算法设计
用一个map保存他的所有节点对应的入度。
用一个队列保存每次入度为0的节点然后pop,pop的顺序就是拓扑排序的顺序。
list <node*> tsort(graph G) {
list<node*> res;
unordered_map<node*, int> inmap;
queue<node*> zeronode;
for (auto next : G.nodes) {//G.nodes是map
inmap[next.second] = next.second->in;
if (next.second->in == 0) {
zeronode.push(next.second);
}
}
while (!zeronode.empty()) {
node* cur = zeronode.front();
zeronode.pop();
res.push_back(cur);
for (auto next : cur->nexts) {
inmap[next]--;
if (inmap[next] == 0) {
zeronode.push(next);
}
}
}
return res;
}