void PostOrderTraverse(Node node, INodeDataProcessor <T> processor)
        {
            if (node == null)
            {
                return;
            }

            PostOrderTraverse(node.Left, processor);
            PostOrderTraverse(node.Right, processor);
            node.ProcessData(processor);
        }
 public void ProcessData(INodeDataProcessor <T> processor)
 {
     processor.Process(Data);
 }
 /// <summary>
 /// Nodes are traversed in the order: Left, Right, Node (LRN)
 /// </summary>
 /// <param name="processor">For processing data stored in nodes encountered during traversal</param>
 /// <remarks>
 /// Where n is the number of nodes in the tree.
 /// BEST CASE- TIME: Ω(n), MEMORY: Ω(n)
 /// AVERAGE CASE- TIME: Θ(n), MEMORY: Θ(n)
 /// WORST CASE- TIME: O(n), MEMORY: O(n)
 /// </remarks>
 public void PostOrderTraverse(INodeDataProcessor <T> processor) => PostOrderTraverse(Root, processor);
 /// <summary>
 /// Nodes are traversed in the order: Left, Node, Right (LNR)
 /// Can be used for sorting data stored in nodes in ascending order
 /// </summary>
 /// <param name="processor">For processing data stored in nodes encountered during traversal</param>
 /// <remarks>
 /// Where n is the number of nodes in the tree.
 /// BEST CASE- TIME: Ω(n), MEMORY: Ω(n)
 /// AVERAGE CASE- TIME: Θ(n), MEMORY: Θ(n)
 /// WORST CASE- TIME: O(n), MEMORY: O(n)
 /// </remarks>
 public void InOrderTraverse(INodeDataProcessor <T> processor) => InOrderTraverse(Root, processor);