/// <summary> /// Static method for building a binary tree with Employees and returning it /// </summary> /// <param name="employee">Current employee(at the start the root)</param> /// <param name="employees">Dictionary with employees</param> /// <returns>Binary tree</returns> public static BinaryTree<Employee> recursiveTreeBuilder(Employee employee, Dictionary<Employee, List<Employee>> employees) { BinaryTree<Employee> tree; //When the node is found the recursion goes deeper foreach (var pair in employees) { //searching for perticular node, so it can build the tree correctly if (pair.Key.FirstName == employee.FirstName) { //taking the left and right child of this node if (pair.Value.Count == 2) { var employeeLeftSubordinate = pair.Value[0]; var employeeRightSubordinate = pair.Value[1]; //building the tree recursively by building first the left subtree and then the right tree = new BinaryTree<Employee>(employee, recursiveTreeBuilder(employeeLeftSubordinate, employees), recursiveTreeBuilder(employeeRightSubordinate, employees)); return tree; } else { var employeeLeftSubordinate = pair.Value[0]; //building the tree recursively by building first the left subtree and then the right tree = new BinaryTree<Employee>(employee, recursiveTreeBuilder(employeeLeftSubordinate, employees), null); return tree; } } } //When it reaches a leaf(node with no children) it returns it as tree with only a root and no children return tree = new BinaryTree<Employee>(employee); }
/// <summary> /// /// </summary> /// <param name="employeeOne">First searched employee</param> /// <param name="employeeTwo">Second searched employee</param> /// <param name="employees">Dictionary(boss, subordinates) with all the employees</param> /// <param name="root">The employee without manager</param> public void Read(Employee employeeOne, Employee employeeTwo, IDictionary<Employee, List<Employee>> employees,ref Employee root) { int countingTheNodes = 0; //Algorithm for reading boss - subordinate Console.WriteLine("Please enter the employee tree relations: (To exit type end)"); while (true) { string line = Console.ReadLine(); if (line == "end") { break; } //Splitting the input line and getting only the meaningfull records char[] splitters = {' ', ',', '-'}; string[] words = line.Split(splitters, StringSplitOptions.RemoveEmptyEntries); // if (words.Length == 2) { //The first word in the line is the boss name and the second is the subordinate ones Employee boss = new Employee(); boss.FirstName = words[0]; Employee subordinate = new Employee(); subordinate.FirstName = words[1]; subordinate.HasBoss = true; if (employees.ContainsKey(boss) && employees[boss].Count == 2) { Console.WriteLine("You cannot enter more then 2 childs for this parent"); } else { //After finding a boss in the Dictionary and inserting his subordinate the flag will become 1, //else there will be new boss record int flagFound = 0; foreach (KeyValuePair<Employee, List<Employee>> pair in employees) { //Checking if the subordinate is not boss in some previous input if (pair.Key.FirstName == subordinate.FirstName) { pair.Key.HasBoss = true; } //If the current pair-boss has only 1 subordinate if (pair.Value.Count == 1) { //checking if the current inputed boss isn't subordinate of someone else if(pair.Value[0].FirstName == boss.FirstName) { boss.HasBoss = true; } } //If the current pair-boss has only 2 subordinates if (pair.Value.Count == 2) { //checking if the current inputed boss isn't subordinate of someone else if((pair.Value[0].FirstName == boss.FirstName) || (pair.Value[1].FirstName == boss.FirstName)) { boss.HasBoss = true; } } //If the boss is already entered in the Dictionary only the subordinate is added in if (pair.Key.FirstName == boss.FirstName) { pair.Value.Add(subordinate); flagFound++; } } //Entering a new record in the dictionary with 1 boss and 1 subordinate if (flagFound == 0) { List<Employee> subordinates = new List<Employee>(); subordinates.Add(subordinate); employees.Add(boss, subordinates); } //counting the entered nodes in the dictionary for the binary tree check countingTheNodes++; } } } if (countingTheNodes == 1) { Console.WriteLine("You've entered non binary tree!"); employees.Clear(); } else { //Method that returns the root(employee without boss) root = SearchingForTheRoot(employees); } }
static void Main(string[] args) { //constructing the main fields var readFromConsole = new ReadFromConsole(); var employeeOne = new Employee(); var employeeTwo = new Employee(); var root = new Employee(); var employees = new Dictionary<Employee, List<Employee>>(); //Filling the fields with data from the console input readFromConsole.Read(employeeOne, employeeTwo, employees,ref root); if (employees.Count == 0) { Console.WriteLine("You didn't enter the tree!"); } else { //Printing the root of Tree to check, if we entered the tree right. if (employees.ContainsKey(root)) { Console.WriteLine("Name of the ROOT: " + root.FirstName); } //Taking the subordinates of the root of the tree for building the EmployeeTree //Creating a tree using the recursiveTreeBuilder(root, root.left/root.right, dictianary with the employees) List<Employee> subordinates = employees[root]; BinaryTree<Employee> employeeTree = new BinaryTree<Employee>(root, TreeBuilder.recursiveTreeBuilder(subordinates[0], employees), TreeBuilder.recursiveTreeBuilder(subordinates[1], employees)); //Printing the tree after the creation Console.WriteLine("Printing the builded tree"); employeeTree.PrintInorder(); //Starting the loop for searching LeastCommonAncestor(LCA) of two employees string line = ""; while (true) { Console.WriteLine("\nPlease enter the first name of the first employee whose boss you search:"); employeeOne.FirstName = Console.ReadLine(); Console.WriteLine("Please enter the first name of the second employee whose boss you search:"); employeeTwo.FirstName = Console.ReadLine(); BinaryTreeNode<Employee> employeeOneNode = new BinaryTreeNode<Employee>(employeeOne); BinaryTreeNode<Employee> employeeTwoNode = new BinaryTreeNode<Employee>(employeeTwo); //Calling the LCA for the builded tree with the (root, firstSearched, secondSearched) and returning their Boss BinaryTreeNode<Employee> searchedBoss = employeeTree.LeastCommonAncestor(employeeOneNode, employeeTwoNode); if (searchedBoss == null) { Console.WriteLine("Your employees doesn't have common ancestor"); } else { Console.WriteLine("The LCA of the two employees is: " + searchedBoss.Value.FirstName); } Console.WriteLine("If you want to exit the search write END, else press Enter to begin new search"); line = Console.ReadLine(); if (line == "END") { break; } } } Console.WriteLine("\nTo exit press any key!"); Console.ReadKey(); }
/// <summary> /// Method for searching a Dictionary with Employees for the employee without a boss /// </summary> /// <param name="employees">Dictionary(boss, subordinates) with all the employees</param> /// <returns>The employee without a boss</returns> private Employee SearchingForTheRoot(IDictionary<Employee, List<Employee>> employees) { Employee root = new Employee(); foreach (KeyValuePair<Employee, List<Employee>> pair in employees) { var employee = pair.Key; if (employee.HasBoss == false) { root = employee; break; } } return root; }