我有一个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 ??
答案 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);
}
}
}
}