C 验证给定的图节点列表的拓扑顺序是否正确

C 验证给定的图节点列表的拓扑顺序是否正确,c,algorithm,graph,topological-sort,C,Algorithm,Graph,Topological Sort,我的任务是编写一些代码,从图中获取节点列表,并确定它们是否处于正确的拓扑顺序 该图在内存中表示如下: typedef struct graph_t* Graph; typedef struct node_t* Node; struct node_t { int id; /*incoming edges*/ Linked_list incoming; /*outgoing edges*/ Linked_list outgoing; }; struct g

我的任务是编写一些代码,从图中获取节点列表,并确定它们是否处于正确的拓扑顺序

该图在内存中表示如下:

typedef struct graph_t* Graph;
typedef struct node_t* Node;

struct node_t {
    int id;
    /*incoming edges*/
    Linked_list incoming;
    /*outgoing edges*/
    Linked_list outgoing;
};

struct graph_t {
    int order;
    int size;
    Node nodes;
};
为了简洁起见,我省略了链表的实现,但它只是链表的标准实现

我还得到了以下算法(伪代码):


L这个想法基本上是基于以下事实:

设L是图G顶点的有序序列,则L是a 图G的拓扑序当且仅当G中的所有边都指向L 向右。换句话说,对于每个有向边(L[i],L[j]),我们有i< j


按照您给出的方法,您正在进行上述检查。检查L中是否有指向左边的边,从上面的事实我们知道,在这种情况下,L不是拓扑序。

基本上,这个想法基于以下事实:

设L是图G顶点的有序序列,则L是a 图G的拓扑序当且仅当G中的所有边都指向L 向右。换句话说,对于每个有向边(L[i],L[j]),我们有i< j

按照您给出的方法,您正在进行上述检查。检查L中是否有指向左边的边,从以上事实我们知道,在这种情况下,L不是拓扑顺序。

引用CLR:

dag G=(V,E)的拓扑排序是其所有顶点的线性排序,因此,如果G包含边(u,V),则u在排序中出现在V之前

这就是您实际在最内层for循环中检查的内容。如果m可以从n访问,但它已经在V中,则表示您在访问n之前已经访问了m。因此L不是拓扑排序的

回答您的下一个问题,您可以实现该行

对于每个节点,m可从n do到达

使用DFS或BFS。因此,在节点n上,您需要检查是否存在从n到m的定向边。

引用CLR:

dag G=(V,E)的拓扑排序是其所有顶点的线性排序,因此,如果G包含边(u,V),则u在排序中出现在V之前

这就是您实际在最内层for循环中检查的内容。如果m可以从n访问,但它已经在V中,则表示您在访问n之前已经访问了m。因此L不是拓扑排序的

回答您的下一个问题,您可以实现该行

对于每个节点,m可从n do到达


使用DFS或BFS。因此,在节点n上,您需要检查是否存在从n到m的定向边。

这不是调试或咨询服务。请看。@Olaf我不是问如何实现这个算法,只是想解释一下它为什么工作。这违反了提问的规则吗?如果是这样,我将删除我的后请再次阅读我的评论。我没有说明您要求实现。这不是调试或咨询服务。请看。@Olaf我不是问如何实现这个算法,只是想解释一下它为什么工作。这违反了提问的规则吗?如果是这样,我将删除我的后请再次阅读我的评论。我没有说你要求执行。
L <- topologically sorted list of nodes
V <- empty list of visited nodes
for each node n in L do
    add n to V
    for each node m reachable from n do
        if m in V then L is not sorted