遍历一棵树"动态给出的级别数

时间:2015-06-27 12:43:20

标签: c# .net list recursion collections

我有一个名为Team的对象,它有一个属性Children,代表一个"子团队列表"在那个团队下

public class Team
{
    public List<Team> Children {get;set;}
} 

我目前有一些代码可以构建所有团队的单个列表,但是你可以看到它的#34;硬编码&#34;在&#34;水平&#34;它失败了:

Team topTeam = GetTopteam();
List<Team> allTeams = new List<Team>();
allTeams.Add(topTeam);
allTeams.AddRange(topTeam.Children);

var childrensChildren = topTeam.Children.SelectMany(r=>r.Children);                   
allTeams.AddRange(childrensChildren);

它继续前进。

我现在想要制作&#34;等级&#34;可配置,如下所示:

 public IEnumberable<Team> GetTeams(int numberOfLevelsDown)
 {
 }

如果我传入1,我只返回一个topteam及其直接孩子的名单。

如果我通过2,我会得到顶级团队,孩子和孩子的孩子

等等。 。

动态地遍历树中的级别最优雅的方法是什么?

2 个答案:

答案 0 :(得分:1)

您可以使用递归来执行此操作。

这种方法签名是由于性能问题而导致无法生成大量中间列表。

public void GetTeams(List<Team> teams, Team team, int level)
{
    if (level == 0)
        return;

    if (team.Children == null)
        return;

    foreach (var t in team.Children)
    {
        teams.Add(t);
        GetTeams(teams, t, level - 1);
    }
}

并像这样使用

var list = new List<Team>();
Team topTeam = GetTopteam();
GetTeams(list, topTeam, 5);
//now you have teams in list

答案 1 :(得分:0)

我多次使用过这种东西。

public static IEnumerable<T> EnumerateDescendants<T>(this T root, Func<T, IEnumerable<T>> children)
{
    yield return root;
    foreach (var child in children(root).SelectMany(x => x.EnumerateDescendants(children)))
    {
        yield return child;
    }
}

像这样使用:

var allTeams = rootTeam.EnumerateDescendants(x => x.Children);

你应该可以修改它:

public static IEnumerable<T> EnumerateDescendants<T>(this T root, Func<T, IEnumerable<T>> children, int maxLevels, int currentLevel = 0)
{
    if (currentLevel <= maxLevels)
    {
        yield return root;
        foreach (var child in children(root).SelectMany(x => x.EnumerateDescendants(children, maxLevels, currentLevel + 1)))
        {
            yield return child;
        }
    }
}

您应该能够像这样使用它:

var allTeamsUpToLevel2 = rootTeam.EnumerateDescendants(x => x.Children, 2);

我可能有&gt; =混合了但是这样的事情应该有用。