如何在树中查找重叠/冗余节点

时间:2012-08-31 19:04:22

标签: c# asp.net algorithm tree

我有一个大层次结构中的节点列表。如何有效地确定哪些节点是列表中任何其他节点的后代?

具体来说,这是一个ASP.NET控件列表。我的代码检查了这些节点及其后代中的每一个,所以我试图消除冗余。

一个简单的例子是这棵树:

         Parent
         /    \
    Gladis    Arthur
    /    \
 Jon      Sam

我的列表包含{ Parent, Jon }

我想编写一个算法,根据Parent节点包含Parent作为后代的事实,将列表简化为Jon

这是代码:

    public class Node
    {
        public Node(string name_, params Node[] children_)
        {
            this.children = children_;
        }
        public string name;
        public Node[] children;
    }

    public class NodeAnalysis
    {
        public Node node;
        public Node containingAncestor = null;
    }

    static void Main(string[] args)
    {
        Node jon = new Node("jon");
        Node parent = new Node("parent",
            new Node("Gladis",
                jon,
                new Node("Sam")),
            new Node("Arthur")
        );

        List<NodeAnalysis> results = new List<NodeAnalysis>();
        results.Add(new NodeAnalysis{ node = parent });
        results.Add(new NodeAnalysis{ node = jon });

        foreach (NodeAnalysis item in results)
        {
            // ??? populate item.containingAncestor
        }
    }

我无法想到一个有效的算法来实现这一目标。我无法控制节点添加到列表的顺序。似乎可以通过检查树和我在遍历它时已在列表中识别的关系来优化它。

**编辑:.parent结构中提供了Node。使用.parent更容易发现祖先关系。

2 个答案:

答案 0 :(得分:1)

这是一种方法:

public static void RemoveDescendants(IList<Node> list)
{
    for (int index = 0; index < list.Count; index++)
        RemoveDescendants(list[index], list);
}
private static void RemoveDescendants(Node node, IList<Node> list)
{
    foreach (var child in node.children)
    {
        list.Remove(child);
        RemoveDescendants(child, list);
    }
}

答案 1 :(得分:0)

我发现这篇文章你可能会觉得有用: http://www.eng.auburn.edu/files/acad_depts/csse/csse_technical_reports/CSSE01-09.pdf

您也可以查看这篇文章: http://www.dmtcs.org/volumes/abstracts/pdfpapers/dm010116.pdf

我相信第一个直接回答你的问题。

希望它有所帮助。