C#挑战员工树
问题描述:
我有一个c#
项目,并且我创建了一个名为Employees
的类。
这个类里面,我有一个新的列表:C#挑战员工树
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你需要让你的经理更接近或更高,还有员工本身。
记住,你可以通过一个董事的ID(你将不得不退回总裁),经理的ID(你必须退回董事),员工的ID(你必须返回经理),总统的身份证自己归还。
考虑到我们可以有比这个例子更大的层次结构,做什么更好的方法来做这项研究。扫描所有列表的成本很高。
使用hastable,dictionary,hashset?
答
递归函数通常用于搜索树。我以为你解决这个变量名的建议:
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;
答
添加有两个功能:
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我添加了异常检查。该dictionnary创建只有一次,再次检查
答
如果你想要做一个遍历只有一次,有这种可能性:
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);
}
}
}
}
你应该在你的命名规则和外壳...'Employees'工作不应该是你的类名,它应该是'员工'(它是一个单一的实体)。 '雇员'应该是'下属'或者_actually_描述它是什么的东西。千万不要混淆像这样的套管。 – maccettura
我同意你的感谢,在急于发贴时我犯下这个错误应该是Employee。这些类的结构并不是真实的,而仅仅是为了展示我们如何在这个树结构中进行这项研究 – devweb
到目前为止,你有什么尝试? –