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