get tree Like Class children使用递归

时间:2016-05-04 21:56:50

标签: c# recursion tree

我构建了一个类Cluster,如下所示:

public  class Cluster
{
    List<Cluster> lstChildClusters=new List<Cluster>();

     public List<Cluster> LstChildClusters
     {    
        get { return lstChildClusters; }
        set { lstChildClusters = value; }
     }

     public    classA alr;
}

我的目标是建立一个能够获得Cluster类型对象的所有孙子的函数。基本上父亲可以拥有0个或更多的儿子,这些儿子可以拥有0个或更多个儿子。

我尝试构建一个递归函数,但它只返回使用下面代码的一个孙子。 这是我建立的功能:

public List<classA> getLevel0Clusters(Cluster cluster,List<classA> list)
    {
        if (cluster.LstChildClusters.Count == 0)
        {
            list.Add(cluster.alr);
          return (list);

        }
        else
        {
            for (int i = 0; i < lstChildClusters.Count - 1; i++)
            {
                return (lstChildClusters[i].getLevel0Clusters(lstChildClusters[i], list));
            }
            return (lstChildClusters[0].getLevel0Clusters(lstChildClusters[0], list));
        }

    }

我正在使用这些实例进行调试:

   Cluster father = new Cluster();
        father.Alr = new Alarm("father");
        Cluster son1 = new Cluster();
        son1.Alr = new Alarm("son1");
        Cluster son2 = new Cluster();
        son2.Alr = new Alarm("son2");
        Cluster grandson1 = new Cluster();
        grandson1.Alr = new Alarm("grandson1");
        Cluster grandson2 = new Cluster();
        grandson2.Alr = new Alarm("grandson2");
        father.LstChildClusters.Add(son1);
        father.LstChildClusters.Add(son2);
        son1.LstChildClusters.Add(grandson1);
        son1.LstChildClusters.Add(grandson2);
List<classA> lst=new lst<ClassA>();
lst=father.getLevel0Clusters(father,  father.LstAlarms);

有没有人知道如何解决这个问题? 提前谢谢

2 个答案:

答案 0 :(得分:2)

您的现有代码存在许多问题,因此我进行了一些重构以使您的程序更简单。

但首先,要回答您的直接问题,现有方法的问题在于,在完成所有结果的汇总之前,您需要调用return。您的代码会查看grandfather并看到它有子节点,因此它会进入for循环并递归调用son1的自身。它看到son1有子节点,因此进入for循环并递归调用自己没有子节点的grandson1,因此它将grandson1添加到列表中然后返回。在找到第一个值后返回外部调用,以便接下来的两个级别返回。因此,列表只有grandson1

因此,要重构您的代码:getLevel0Clusters方法不需要传递Cluster(因为它在Cluster类中定义它可以使用this )和List<classA>(因为它可以根据需要生成一个)。

因此,您的getLevel0Clusters可以变成这样:

public List<classA> getLevel0Clusters()
{
    return new[] { this.alr, }
        .Concat(this.LstChildClusters
            .SelectMany(child => child.getLevel0Clusters()))
        .ToList();
}

为了获得编译的所有内容,我将示例代码修改为:

Cluster father = new Cluster();
father.alr = new classA("father");
Cluster son1 = new Cluster();
son1.alr = new classA("son1");
Cluster son2 = new Cluster();
son2.alr = new classA("son2");
Cluster grandson1 = new Cluster();
grandson1.alr = new classA("grandson1");
Cluster grandson2 = new Cluster();
grandson2.alr = new classA("grandson2");
father.LstChildClusters.Add(son1);
father.LstChildClusters.Add(son2);
son1.LstChildClusters.Add(grandson1);
son1.LstChildClusters.Add(grandson2);
List<classA> lst = father.getLevel0Clusters();

......和你的课程一样:

public class Cluster
{
    List<Cluster> lstChildClusters = new List<Cluster>();

    public List<Cluster> LstChildClusters
    {
        get { return lstChildClusters; }
        set { lstChildClusters = value; }
    }
    public classA alr;

    public List<classA> getLevel0Clusters()
    {
        return new[] { this.alr, }
            .Concat(this.LstChildClusters
                .SelectMany(child => child.getLevel0Clusters()))
            .ToList();
    }
}

public class classA
{
    public string Name;
    public classA(string name)
    {
        this.Name = name;
    }
}

当我运行你的示例代码时,我得到了这个结果:

result

答案 1 :(得分:1)

问题是,只要找到一个后代,就会返回到调用程序。 计数的值除了 0 与正数之外无效:您进入循环,调用 lstChildClusters [0] .getLevel0Clusters(lstChildClusters [0] ,并返回该值而不必费力地增加 i 并继续循环。

相反, for 循环必须将每个返回值添加到列表中。 循环完成后,您可以返回调用程序。