using System.Collections.Generic;
public static void Main()
Node a = new Node { Name = "A" };
Node a1 = new Node { Name = "A1" };
Node a11 = new Node { Name = "A11" };
Node a111 = new Node { Name = "A111" };
Node a112 = new Node { Name = "A112" };
Node a113 = new Node { Name = "A113" };
Node b11 = new Node { Name = "B11" };
Node b111 = new Node { Name = "B111" };
Node b112 = new Node { Name = "B112" };
Console.WriteLine("Original tree:");
Console.WriteLine(a.ToString());
List<Node> selectedNodes = new List<Node> { a111, a112, b111 };
Console.WriteLine("Selected nodes: " + string.Join(", ", selectedNodes.Select(n => n.Name)));
Node common = Node.FindClosestCommonAncestor(selectedNodes);
Console.WriteLine("\r\nClosest common ancestor subtree:");
Console.WriteLine(common.ToString());
public int Id { get; set; }
public string Name { get; set; }
public Node Parent { get; set; }
public List<Node> Children { get; set; }
Children = new List<Node>();
public void AddChild(Node node)
public List<Node> AncestorsAndSelf
List<Node> list = new List<Node>() { this };
get { return AncestorsAndSelf.Count; }
public static Node FindClosestCommonAncestor(IEnumerable<Node> selectedNodes)
IEnumerable<Node> commonAncestors = selectedNodes.First().AncestorsAndSelf;
foreach (Node n in selectedNodes.Skip(1))
commonAncestors = commonAncestors.Intersect(n.AncestorsAndSelf);
return commonAncestors.OrderByDescending(n => n.Depth).FirstOrDefault();
public override string ToString()
private string ToString(string indent)
string s = indent + Name + "\r\n";
foreach (Node child in Children)
s += child.ToString(indent + " ");