我对拓扑排序知之甚少,但我认为我知道的足够多,可以发表明智的评论。任何人都应该随时编辑此回复。
我看到这个实现有几个问题。一些与 C 有关,另一些与算法有关,所以让我一次过一遍。
问题定义。
拓扑排序确实被定义为有向图中元素的优先级。但是,仅凭这句话并不能完全定义问题。具体来说,拓扑排序是从指定源顶点开始的图元素的优先级。例如,假设您有以下有向图:
a -> b
b -> c
c -> a
如果你从 vertex 开始a
,你的拓扑顺序应该是{a, b, c}
. 如果你从 vertex 开始c
,你的拓扑顺序应该是{c, a, b}
. 因此,如果没有源顶点,问题定义就毫无意义。这种顶点的一种选择可以是图中没有指向它的边的某个顶点,即每个入射边都是出边。
要记住的另一件事是图形连通性。从任何其他顶点到达任何顶点并不总是可能的。因此,在实现此类算法时值得牢记。
好的数据结构是好的算法的关键。如果你想在有向图中对事物进行排序,最好的办法是创建一个有向图数据结构,这本身就涉及创建一个Node
数据结构和一个Edge
数据结构。我建议查找邻接列表。一旦你有了这样的数据结构,就可以在图上运行广度优先搜索,并且你会得到你的拓扑优先级作为一个简洁的结果。
在实现邻接列表时,您仍然需要将所有元素存储在一个地方。链表通常不是最好的方法,因为插入一个列表需要恒定的时间(假设对数据进行排序),搜索一个需要线性时间。那是次优的。正如@David RF所建议的那样,红黑树和AVL 树将是要走的路。但是,我不会从这个优化开始。只要你有一个完善的工作算法,你总是可以改进你的存储数据结构。毕竟,链表和搜索树的接口是一样的。
如果您使用正确的算法,该算法可以很快。我在实践中没有处理过拓扑排序,所以我不知道每一个复杂性和每一个边缘情况。但!如果您使用传统的节点边数据结构进行广度优先搜索(请注意,边可以在节点内隐式定义),您的搜索本身应该使用广度优先搜索花费线性时间。
我已经阅读了你的算法,我不得不承认我并没有完全理解你的大列表和小列表的概念。模棱两可的名字并没有真正的帮助。也许它通过隐藏在某个地方的一个小错误来完成这项工作,但它不太可读。也许其他人可以评论您当前的实施。