C#挑战员工树

时间:2017-10-11 19:59:58

标签: c# tree

我有一个c#项目,我创建了一个名为Employees的班级 在这个课程中,我有一个新的列表:

public class Employees
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int? ManagerId { get; set; }
    public List<Employees> employees { get; set; }
}

想象一下,我在图像中显示了以下结构:
companytree

然后在主程序中,我有这个结构来表示上面的图片:

class Program
{
    static void Main(string[] args)
    {
        var root = new Employees()
        {
            Id = 15,
            Name = "President",
            employees = new List<Employees>()
            {
                new Employees() {

                    Id = 23, ManagerId = 15, Name = "Director23",
                    employees = new List<Employees>()
                    {
                        new Employees() {
                            Id = 21, ManagerId = 23, Name = "Manager21",
                            employees = new List<Employees>()
                            {
                                new Employees() { Id = 31, ManagerId=21, Name = "Employee31" },
                                new Employees() { Id = 41, ManagerId=21, Name = "Employee41" },
                                new Employees() { Id = 51, ManagerId=21, Name = "Employee51" }
                            }
                        },

                        new Employees() {
                            Id = 22, ManagerId = 23, Name = "Manager22",
                            employees = new List<Employees>()
                            {
                                new Employees() { Id = 32, ManagerId=22, Name = "Employee32" },
                                new Employees() { Id = 42, ManagerId=22, Name = "Employee42" },
                                new Employees() { Id = 52, ManagerId=22, Name = "Employee52" }
                            }
                        }
                    }
                },

                new Employees() {

                    Id = 25, ManagerId = 15, Name = "Director25",
                    employees = new List<Employees>()
                    {
                        new Employees() {
                            Id = 51, ManagerId = 25, Name = "Manager51",
                            employees = new List<Employees>()
                            {
                                new Employees() { Id = 61, ManagerId=51, Name = "Employee61" },
                                new Employees() { Id = 71, ManagerId=51, Name = "Employee71" },
                                new Employees() { Id = 81, ManagerId=51, Name = "Employee81" }
                            }
                        },

                        new Employees() {
                            Id = 62, ManagerId = 25, Name = "Manager62",
                            employees = new List<Employees>()
                            {
                                new Employees() { Id = 72, ManagerId=62, Name = "Employee72" },
                                new Employees() { Id = 82, ManagerId=62, Name = "Employee82" }
                            }
                        }
                    }
                }

            }
        };

        Console.ReadLine();
    }
}

如何创建一个函数,我传递员工的树根列表和公司任何员工的ID,您需要让经理更接近或更高,以及员工本身。

记住你可以传递导演的身份证明(你必须归还总统),经理的身份证明(你必须归还导演),雇员的身份证明(你必须归还经理),总统的身份证明归还自己。

考虑到我们可以拥有比这个例子更大的层次结构,有什么更好的方法来进行这项研究。扫描所有列表的成本很高。

使用hastable,dictionary,hashset ??

3 个答案:

答案 0 :(得分:0)

递归函数通常用于搜索树。我假设您按照建议修改变量名称:

public static Employee FindById(Employee root, int id) {
    if (root.Id == id)
        return root;
    else if (root.Employees != null) {
        foreach (var e in root.Employees) {
            var pe = FindById(e, id);
            if (pe != null)
                return pe;
        }
    }
    return null;
}

要使用,请找到员工,然后找到经理:

var emp = FindById(root, 51);
var manager = emp.ManagerId.HasValue ? FindById(root, emp.ManagerId.Value) : null;

答案 1 :(得分:0)

添加两个功能:

public static IDictionary<int, Employees> EmployeesToDictionary(Employees employees)
{
    var dictionary = new Dictionary<int, Employees>();
    EmployeesToDictionary(employees, dictionary);
    return dictionary;
}

private static void EmployeesToDictionary(Employees employees, IDictionary<int, Employees> dictionary)
{
    if (employees == null) return;
    dictionary.Add(employees.Id, employees);
    if (employees.employees == null) return;
    foreach (var sub in employees.employees)
    {
        EmployeesToDictionary(sub);
    }
}

用法:

var id = 5;
var dict = EmployeesToDictionary(root);
var employee = dict[id];
var manager = dict[employee.ManagerId.Value];

编辑: @haindl文档承认失败是的你是对的。 @devweb我已经添加了异常检查。该词典只创建一次,再次检查

答案 2 :(得分:0)

如果你只想进行一次遍历,就有这种可能性:

public static void FindById(Employees root, int id, out Employees employees, out Employees manager)
{
    employees = manager = null;
    // todo stack
    var stack = new Stack<Employees>();
    stack.Push(root);
    // all managers seens
    var managers = new List<Employees>();
    while (stack.Count > 0)
    {
        var e = stack.Pop();
        if (e.Id == id) // if found
        {
            employees = e;
            manager = managers.FirstOrDefault(m => m.Id == e.ManagerId);
            return;
        }
        else if (e.employees != null)
        {
            // add only managers with employee
            managers.Add(e);
            foreach (var ep in e.employees)
            {
                stack.Push(ep);
            }
        }
    }
}