使用C#代码实现拓扑排序MyZony

尊重他人的劳动成果,贴上参考的资料地址,本文仅作学习记录之用。

看了第二篇参考资料才大致了解,在此记录一下。

先来一个基本定义:

在图论中,拓扑排序(TopologicalSorting)是一个有向无环图(DAG,DirectedAcyclicGraph)的所有顶点的线性序列。且该序列必须满足下面两个条件:

有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说。

例如,有一个集合它的依赖关系如下图:

可以看到他有一个依赖关系:

这个就是一个DAG图,我们要得到它的拓扑排序,一个简单的步骤如下:

按照以上步骤,我们来进行一个排序试试。

最后的排序结果就是:

ModuleD->ModuleE->ModuleB->ModuleC->ModuleA

emmmm,其实一个有向无环图可以有一个或者多个拓扑序列的,因为有的时候会存在一种情况,即以下这种情况:

这个时候你就可能会有这两种结果

D->E->B->C->F->A

D->E->B->F->C->A

因为F与C是平级的,他们初始化顺序即便不同也没有什么影响,因为他们的依赖层级是一致的,不过细心的朋友可能会发现这个顺序好像是反的,我们还需要将其再反转一次。

上面这种方法仅适用于已知入度的时候,也就是说这些内容本身就是存在于一个有向无环图之中的,如果按照以上方法进行拓扑排序,你需要维护一个入度为0的队列,然后每次迭代移除入度为0顶点所指向的顶点入度。

例如有以下图:

按照我们之前的算法,

这样反复循环,最终队列全部清空,退出循环,得到拓扑排序的结果4,5,2,0,3,1。

在参考资料1的代码当中使用的是深度优先算法,它适用于有向无环图。

有以下有向环图G2:

对上图G2进行深度优先遍历,首先从入度为0的顶点A开始遍历:

它的步骤如下:

因此最后的访问顺序就是A->B->C->E->D->F->G,注意顺序还是不太对哦。

看起来跟之前的方法差不多,实现当中,其Sort()方法内部包含一个visited字典,用于标记已经访问过的顶点,sorted则是已经排序完成的集合列表。

在字典里Key是顶点的值,其value值用来标识是否已经访问完所有路径,为true则表示正在处理该顶点,为false则表示已经处理完成。

现在我们来写实现吧:

publicstaticIListSort(IEnumerablesource,Func>getDependencies){ varsorted=newList(); varvisited=newDictionary(); foreach(variteminsource) { Visit(item,getDependencies,sorted,visited); } returnsorted;}publicstaticvoidVisit(Titem,Func>getDependencies,Listsorted,Dictionaryvisited){ boolinProcess; varalreadyVisited=visited.TryGetValue(item,outinProcess);//如果已经访问该顶点,则直接返回 if(alreadyVisited) {//如果处理的为当前节点,则说明存在循环引用 if(inProcess) { thrownewArgumentException("Cyclicdependencyfound."); } } else {//正在处理当前顶点 visited[item]=true;//获得所有依赖项 vardependencies=getDependencies(item);//如果依赖项集合不为空,遍历访问其依赖节点 if(dependencies!=null) { foreach(vardependencyindependencies) {//递归遍历访问 Visit(dependency,getDependencies,sorted,visited); } }//处理完成置为false visited[item]=false; sorted.Add(item); }}顶点定义:

//Item定义publicclassItem{//条目名称 publicstringName{get;privateset;}//依赖项 publicItem[]Dependencies{get;set;} publicItem(stringname,paramsItem[]dependencies) { Name=name; Dependencies=dependencies; } publicoverridestringToString() { returnName; }}调用:

staticvoidMain(string[]args){ varmoduleA=newItem("ModuleA"); varmoduleC=newItem("ModuleC",moduleA); varmoduleB=newItem("ModuleB",moduleC); varmoduleE=newItem("ModuleE",moduleB); varmoduleD=newItem("ModuleD",moduleE); varunsorted=new[]{moduleE,moduleA,moduleD,moduleB,moduleC}; varsorted=Sort(unsorted,x=>x.Dependencies); foreach(variteminsorted) { Console.WriteLine(item.Name); } Console.ReadLine();}

THE END
1.初阶数据结构常见五大排序算法及部分算法优化讨论如下图,对于只有一个数字3来说,它就是有序的,这时如果我们要插入44,则跟前面已经排好的3比较,44大于3,44插入在3的后面,排序完成,要插入38,38跟前面的数据比较,38小于44,44往后挪,33大于3,33插入在3的后面,数据有序,排序结束,后面同理。 代码语言:javascripthttps://cloud.tencent.com.cn/developer/article/2476881
2.2026考研计算机知识点盘点:排序考研今天新东方在线考研频道小编为各位考生整理了“2026考研计算机知识点盘点:排序”,相关内容。专业、实用的计算机考研复习备考内容,能使大家更有效率的掌握相关知识点,避免盲目学!更多计算机考研复习精彩内容,时刻关注新东方在线考研频道! 点击下载>考研计算机408历年真题|考试大纲 https://kaoyan.koolearn.com/20241220/1789631.html
3.Day14中高难度算法挑战拓扑排序拓扑排序,基本原理是每次都把入度为0的点移除。注意这些点的先后顺序其实是没有关系的。 fromtypingimportListfromcollectionsimportdefaultdict,dequeclassSolution:""" @param num_courses: a total of n courses @param prerequisites: a list of prerequisite pairs https://www.bilibili.com/read/cv25624858
4.数据结构与算法——拓扑排序(引例拓扑排序伪代码代码关键简介:数据结构与算法——拓扑排序(引例、拓扑排序、伪代码、代码、关键路径问题) 引例 以一个例子开始引进拓扑排序: 根据这个表,我们可以每个课程表示为图的顶点,<V,W>表示边,V为W的预修课程,画出图: 这样就构成了一个AOV网络,即Activity On Vertex 网络。 https://developer.aliyun.com/article/1531072
5.拓扑排序两种实现的代码示例腾讯云开发者社区如果拓扑排序结果中的节点数量等于图中的节点数量,说明排序成功;否则,图中存在环。 下面是 Kahn 算法的 Java 代码实现: import java.util.*; /** * Kahn 算法 * */ public class TopologicalSort { public static List<Integer> kahnTopologicalSort(Map<Integer, List<Integer>> graph, int numNodes) { https://cloud.tencent.com/developer/news/1883128
6.拓扑排序伪代码有向无环图topological sorting with DFS O(n) foreach node:ifnot marked:if(dfs(node)==CYCLE)returnCYCLEreturnOKdfs(node):ifnodeismarkedasvisited:returnOKifnodeismarkedasvisiting:returnCYCLE mark nodeasvisitingforeach new_nodeinnode.neighbors:ifdfs(new_node)==CYCPEreturnCYCLE https://www.jianshu.com/p/9fff9e3be46a
7.拓扑排序示例运行结果 代码简介 代码仓库 作者 SorveyWu(sorvey) 编辑于:2024-10-11 14:49 拓扑排序示例 提示:本站严禁涉政、违法等无关技术的内容 发送 学习嵌入式的绝佳套件,esp8266开源小电视成品,比自己去买开发板+屏幕还要便宜,省去了焊接不当搞坏的风险。 蜂鸣版+触控升级仅36元,更强的硬件、价格全网最低。https://jsrun.net/KYtKp
8.详解Java实现拓扑排序算法java但只要满足即是拓扑排序序列。 另外观察 1 2 4 3 6 5 7 9这个序列满足我们所说的有关系的节点指向的在前面,被指向的在后面。如果完全没关系那不一定前后(例如1,2) 三、拓扑排序代码实现 对于拓扑排序,如何用代码实现呢?对于拓扑排序,虽然在上面详细介绍了思路和流程,也很通俗易懂。但是实际上代码的实现还是https://www.jb51.net/article/214992.htm
9.拓扑排序C++代码实现51CTO博客拓扑排序 C++代码实现,#include<iostream>usingnamespacestd;#defineMAX10000000#defineMAX_VERTEX_NUM20/*顺序栈的定义*/#defineStack_https://blog.51cto.com/u_5173797/7251949
10.拓扑排序c++代码拓扑排序c++代码 什么是拓扑排序 拓扑排序是对一个有向图构造拓扑序列的过程,使得该序列满足:每个顶点出现且只出现一次;若存在一条从顶点A到顶点B的路径,那么在序列中顶点A出现在顶点B的前面。拓扑排序可以用来判断一个有向图是否为DAG (有向无环图)。如果一个有向图可以被拓扑排序,那么这个有向图就是DAGhttps://wenku.baidu.com/view/d6fe9487142ded630b1c59eef8c75fbfc77d94f4.html
11.拓扑排序·NOIP·看云拓扑排序指的是将有向无环(又称“DAG”图)中的顶点按照图中指定的先后顺序进行排序。 图的拓扑排序是对有向无环图来说的,无向图和有环图没有拓扑排序,或者说不存在拓扑排序,对于一个有向无环图G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若图G存在边,则u在线性序列中https://www.kancloud.cn/dream_fly/test/981925
12.C语言数据结构拓扑排序(代码演示)拓扑排序代码拓扑排序是对有向图进行排序的一种算法,它可以得到一个顶点的线性序列,使得对于图中的任意一条有向边 (u, v),顶点 u 在序列中都出现在顶点 v 的前面。换句话说,如果存在一条有向边 (u, v),那么在排序后的序列中,顶点 u 出现在顶点 v 的前面。 https://blog.csdn.net/m0_74000825/article/details/135004907
13.同步语言的时间可预测多线程代码生成方法?4.2 基于S-CGA的数据依赖图构造 在串行代码生成中,我们将属于同一个时钟等价类的 S-CGA 等式放在同一个时钟节点上,并对这些等式按 照读写数据依赖关系进行排序(如果为偏序,则采用拓扑排序).从而按照时钟树的顺序,生成串行代码的控制结 构.而在控制结构内,按照经过排序的 S-CGA 等式生成对应的程序代码. 在多https://jos.org.cn/jos/article/pdf/4984
14.换一种角度理解拓扑排序概念 拓扑排序可以用来解决调度问题,比如一些任务之间存在依赖关系,必须先完成某些任务再做其它任务 上图是一些任务之间的依赖关系,按书本上的定义是: 0依赖1 2依赖0和3 那么可能的任务调度顺序是:1,0,3,2或3,1,0,2 因为任务数量比较少,所以比较容易看出拓扑序 https://zhuanlan.zhihu.com/p/663375464