using System.Collections.Generic;
public int Id { get; set; }
public List<int> ChildrenIds { get; set; }
public Node(int id, List<int> childrenIds = null)
ChildrenIds = childrenIds ?? new List<int>();
public static class TreeExtensions
public static List<int> GetRelatedNodeIds(this Node root, int targetNodeId)
var targetNodePath = FindPathToNode(root, targetNodeId);
if (targetNodePath == null)
var relatedNodeIds = new HashSet<int>();
foreach(var nodeId in targetNodePath)
relatedNodeIds.Add(nodeId);
foreach (var ancestorId in targetNodePath)
var ancestor = FindNodeById(root, ancestorId);
relatedNodeIds.UnionWith(GetAllDescendantIds(ancestor));
return relatedNodeIds.ToList();
private static List<int> FindPathToNode(Node root, int targetNodeId)
if (root.Id == targetNodeId)
return new List<int> { root.Id };
foreach(var childId in root.ChildrenIds)
var child = FindNodeById(root, childId);
var path = FindPathToNode(child, targetNodeId);
private static Node FindNodeById(Node root, int nodeId)
foreach(var childId in root.ChildrenIds)
var child = FindNodeById(root, childId);
private static HashSet<int> GetAllDescendantIds(Node node)
var descendants = new HashSet<int>();
descendants.Add(node.Id);
foreach(var childId in node.ChildrenIds)
var child = FindNodeById(node, childId);
descendants.UnionWith(GetAllDescendantIds(child));
public static void Main(string[] args)
var root = new Node(1, new List<int> { 2, 3, 4 });
var node2 = new Node(2, new List<int>{5,6});
var node3 = new Node(3, new List<int>{7});
var nodes = new List<Node>() { root, node2, node3, node4, node5, node6, node7 };
var relatedNodeIds = root.GetRelatedNodeIds(5);
relatedNodeIds = root.GetRelatedNodeIds(3);
relatedNodeIds = root.GetRelatedNodeIds(1);
relatedNodeIds = ((Node)null).GetRelatedNodeIds(1);
Console.WriteLine($"Related Node IDs for target 5: {string.Join(", ", root.GetRelatedNodeIds(5))}");
Console.WriteLine($"Related Node IDs for target 3: {string.Join(", ", root.GetRelatedNodeIds(3))}");
Console.WriteLine($"Related Node IDs for target 1: {string.Join(", ", root.GetRelatedNodeIds(1))}");
Console.WriteLine($"Related Node IDs for target in null tree: {string.Join(", ", ((Node)null).GetRelatedNodeIds(1))}");