从树(图)中获取有序列表的最有效方法是什么?

时间:2012-11-21 22:02:09

标签: c# algorithm tree diagram

我正在使用一个图表控件,其中包含一个Node,其中包含指向其父项及其子项的链接。我想整理树,但要按顺序。什么是最快,最有效的方法;最好是在C#中。

这是树的一个例​​子。我很难想出订单的良好描述,所以我道歉。订单应按创建顺序列出所有节点。例如,在树击中,有效顺序将是(Root,A,B,C,G,D,H,E,F)。此顺序保证在其父级之前没有节点添加到列表中。

Simple Diagram to demo my question

1 个答案:

答案 0 :(得分:1)

您的图表不是树,因为一个节点可以有多个父节点。我假设你有directed acyclic graph (DAG)。您的有序列表称为该有向图的toplogical ordering,当且仅当图形是非循环时才存在。幸运的是,这样的排序可以通过线性运行时间来生成。

您可以使用从根开始的深度优先搜索来执行此操作:

public static IEnumerable<Node> GetTopologicalGraphOrdering(IEnumerable<Node> roots)
{
    var list=new List<Node>();
    var visited=new HashSet<Node>();

    Action<Node> visit = null;
    visit = (n)=>
    {
       if(visited.Add(n)
       {
           foreach(Node child in n.Children)
           {
               visit(child);
           }
           list.Add(n)
       }
    }

    foreach(Node n in roots)
    {
       visit(n);
    }

    return list.Reverse();
}

(未经测试的记事本代码)

请注意,这种天真的实现会导致深层图形的堆栈溢出。如果这成为问题,请切换到显式堆栈或替代算法。

阅读维基百科文章Topological sorting了解更多详情。