/** Recursive call to insert element in tree */
        public BinaryItem <T> Insert(BinaryItem <T> current, T item)
        {
            if (current == null)
            {
                current = new BinaryItem <T>(item);
                return(current);
            }

            int comparison = item.CompareTo(current.Value);

            if (comparison <= 0)
            {
                // insert at left of tree
                current.Left = Insert(current.Left, item);
                //return current.Left;
            }
            else
            {
                current.Right = Insert(current.Right, item);
                //return current.Right;
            }

            // return current, instead of left or right, because
            // being called recursively, we need to remeber the path traversed to reach here
            // if we return left or right, we keep returning the element where we insert into tree
            // which will remove all nodes in tree
            return(current);
        }
        public void Insert3(BinaryItem <T> current, T item)
        {
            BinaryItem <T> after  = current;
            BinaryItem <T> before = null;

            // find place to insert into tree
            while (after != null)
            {
                before = after;

                int comparison = item.CompareTo(current.Value);
                if (comparison <= 0)
                {
                    // keep finding until we find a null element
                    after = after.Left;
                }
                else
                {
                    after = after.Right;
                }
            }

            var newNode           = new BinaryItem <T>(item);
            int currentComparison = item.CompareTo(before.Value);

            if (currentComparison <= 0)
            {
                before.Left = newNode;
            }
            else
            {
                before.Right = newNode;
            }
        }
        /** Insert the element at its correct place in the tree  */
        public void Insert(T item)
        {
            // insert at root if empty
            if (Root == null)
            {
                Root = new BinaryItem <T>(item);
                return;
            }

            // else find appropriate place and insert there
            Insert(Root, item);
        }
        public static void Print(BinaryItem <T> root, int topMargin = 2, int leftMargin = 2)
        {
            if (root == null)
            {
                return;
            }
            int rootTop = Console.CursorTop + topMargin;
            var last    = new List <NodeInfo>();
            var next    = root;

            for (int level = 0; next != null; level++)
            {
                var item = new NodeInfo {
                    Node = next, Text = next.Value.ToString()
                };
                if (level < last.Count)
                {
                    item.StartPos = last[level].EndPos + 1;
                    last[level]   = item;
                }
                else
                {
                    item.StartPos = leftMargin;
                    last.Add(item);
                }
                if (level > 0)
                {
                    item.Parent = last[level - 1];
                    if (next == item.Parent.Node.Left)
                    {
                        item.Parent.Left = item;
                        item.EndPos      = Math.Max(item.EndPos, item.Parent.StartPos);
                    }
                    else
                    {
                        item.Parent.Right = item;
                        item.StartPos     = Math.Max(item.StartPos, item.Parent.EndPos);
                    }
                }
                next = next.Left ?? next.Right;
                for (; next == null; item = item.Parent)
                {
                    Print(item, rootTop + 2 * level);
                    if (--level < 0)
                    {
                        break;
                    }
                    if (item == item.Parent.Left)
                    {
                        item.Parent.StartPos = item.EndPos;
                        next = item.Parent.Node.Right;
                    }
                    else
                    {
                        if (item.Parent.Left == null)
                        {
                            item.Parent.EndPos = item.StartPos;
                        }
                        else
                        {
                            item.Parent.StartPos += (item.StartPos - item.Parent.EndPos) / 2;
                        }
                    }
                }
            }
            Console.SetCursorPosition(0, rootTop + 2 * last.Count - 1);
        }