从父子节点集合中查找死节点

时间:2017-08-21 15:55:21

标签: c# algorithm linq

我有一个具有父子关系的自定义节点的集合。每个节点可以是复合类型(其中包含其他子节点)或简单类型(叶级节点)

我想编写一个函数,它将为我提供所有死节点的列表。 例如,这里是节点集合

enter image description here

基于上述情况,p2,p3,p8,p9,p10,p6,c1是死节点(因为它们的层次结构中没有任何简单节点)

我需要一个函数

private List<NodeEntity> GetDeadNodes(List<NodeEntity> originalList) 

这是具有原始列表的函数

private List<NodeEntity> GetOriginalList()
{
    var list = new List<NodeEntity>()
    {
        new NodeEntity() {Code = "P1", ParentCode = "001", Type = NodeType.Composite},
        new NodeEntity() {Code = "C1", ParentCode = "001", Type = NodeType.Composite},
        new NodeEntity() {Code = "P2", ParentCode = "P1", Type = NodeType.Composite},
        new NodeEntity() {Code = "P3", ParentCode = "P2", Type = NodeType.Composite},
        new NodeEntity() {Code = "P8", ParentCode = "P3", Type = NodeType.Composite},
        new NodeEntity() {Code = "P9", ParentCode = "P3", Type = NodeType.Composite},
        new NodeEntity() {Code = "P4", ParentCode = "P1", Type = NodeType.Composite},
        new NodeEntity() {Code = "L3", ParentCode = "P1",  Type = NodeType.Simple},
        new NodeEntity() {Code = "P6", ParentCode = "P1",  Type = NodeType.Composite},
        new NodeEntity() {Code = "P10", ParentCode = "P4",  Type = NodeType.Composite},
        new NodeEntity() {Code = "L2", ParentCode = "P4",  Type = NodeType.Simple},
        new NodeEntity() {Code = "P5", ParentCode = "P4",  Type = NodeType.Composite},
        new NodeEntity() {Code = "L1", ParentCode = "P5",  Type = NodeType.Simple}
    };
    return list;
}

2 个答案:

答案 0 :(得分:3)

您可以从每个Simple节点对树进行简单扫描,以收集要保留的所有节点(伪代码):

put Simple nodes in a Set

while node in Set
  add node to a 'seen' list
  add parent to Set

dead nodes = all nodes except 'seen' nodes

答案 1 :(得分:0)

你可以尝试类似的东西。

    private List<NodeEntity> GetDeadNodes(List<NodeEntity> originalList)
    {
        var rest = originalList.ToList();

        // Remove simple nodes and their ascendants.
        // The rest will be dead nodes.
        var simpleNodes = originalList.Where(n => n.Type == NodeType.Simple);
        foreach (var simpleNode in simpleNodes)
        {
            rest.Remove(simpleNode);
            RemoveAscendants(rest, simpleNode);
        }

        return rest;
    }

    private void RemoveAscendants(List<NodeEntity> rest, NodeEntity node)
    {
        var parent = rest.SingleOrDefault(n => n.Code == node.ParentCode);

        // We have reached the root node.
        if (parent == null)
        {
            return;
        }
        rest.Remove(parent);
        RemoveAscendants(rest, parent);
    }