C#遍历层次结构没有递归

时间:2014-10-13 04:20:10

标签: c# recursion iteration stack-overflow

我需要一只手将我的递归函数转换为循环,因为我试图这样做几个小时。原因是我一直遇到StackOverflow异常。

请检查以下代码:

private List<int> GetManagers(Employee employee, List<Employee> employeeList)
{
    List<int> collection = new List<int>();
    if (employee.DirectManagers.Any())
    {
        var managers = employeeList.Where(x => employee.DirectManagers.Any(y => y.Equals(x.Id)));
        foreach (var manager in managers)
        {
            if (!collection.Any(x => x.Equals(manager.Id)))
                collection.Add(manager.Id);
            if (manager.DirectManagers.Any())
                collection.AddRange(GetManagers(manager, employeeList));
        }
    }

    return collection;
}

修改:此处有更多代码

foreach (var employee in employeeList)
{
    List<int> allManagers = new List<int>();
    allManagers = GetManagers(employee, employeeList);

    // Do something with allManagers found here that does not affect the collection
}

public class Employee
{
    public int Id { get; set; }
    public int? DepartmentId { get; set; }
    public List<int> DirectManagers { get; set; }
    public List<int> DirectSubordinates { get; set; }
    public int Counter { get; set; }
}

    var employeeList = context.AdministratorProfiles
        .Where(x => !x.dateResigned.HasValue && x.departmentID.HasValue)
        .Select(x => new Employee {
            Id = x.id,
            DepartmentId = x.departmentID,
            Counter = 0,
            DirectManagers = x.Managers.Select(y => y.managerID).ToList(),
            DirectSubordinates = x.Subordinates.Select(y => y.adminID).ToList()
        }).ToList(); // TODO: Add active account here

基本上,这样做是因为我试图让所有员工的经理都参与其中。由于员工人数众多,我经常遇到StackOverflow异常。我需要一只手,如果那里的任何人可以伸出援助之手,我会很感激。谢谢。

编辑:现在,我列出了所有代码。所以也许你可以更好地理解。基本上,我要做的是循环每一个员工来完成工作,首先我必须有一份工作清单。该工作清单将排除所有经理或经理的经理以形成最终名单。

2 个答案:

答案 0 :(得分:2)

你的问题不是递归而是循环引用。您可以使用模式访问者来解决此问题。 (在此模式中,您使用递归方法标记所有访问过的实体,如果再次访问此实体,则只返回)

答案 1 :(得分:0)

您可以执行以下操作:

...
Dictionary<int, bool> processed = new Dictionary<int, bool>();
Queue<Employee> managersQueue = new Queue<Employee>();
managersQueue.Enqueue(employee);

while (managersQueue.Any())
{
    var currentEmployee = stack.Dequeue();
    var managers = employeeList.Where(x => currentEmployee.DirectManagers.Any(y => y.Equals(x.Id)));
    foreach (var manager in managers)
    {
        if (processed.ContainsKey(manager.Id)) continue;
        processed.Add(manager.Id, true);
        managersQueue.Enqueue(manager);
    }
}
return processed.Select(x => x.Key).ToList();

这只是一个基本的概述,你可以如何迭代地执行此操作,显然我不知道你的代码库或确切的调用方式。