/*
         *  Given a BST (Binary Search Tree) that may be unbalanced,
         *  convert it into a balanced BST that has minimum possible height.
         *
         *  Time Complexity: O(n)
         */
        public static LinkedList_To_BST_Node BuildBalancedTreeFromTree(LinkedList_To_BST_Node head)
        {
            LinkedList <int> traversedList = new LinkedList <int>();

            _InOrderTraverse(head, traversedList);
            return(BuildTree1(traversedList));
        }
        private static void _InOrderTraverse(LinkedList_To_BST_Node node, LinkedList <int> linkedList)
        {
            if (node == null)
            {
                return;
            }

            _InOrderTraverse(node.Left, linkedList);
            linkedList.AddLast(node.ID);
            _InOrderTraverse(node.Right, linkedList);
        }
        private static LinkedList_To_BST_Node _BuildTreeRecur1(int n)
        {
            if (n <= 0)
            {
                return(null);
            }

            LinkedList_To_BST_Node leftNode = _BuildTreeRecur1(n / 2);

            LinkedList_To_BST_Node root = new LinkedList_To_BST_Node(_currentLinkedListNode.Value);

            _currentLinkedListNode = _currentLinkedListNode.Next;

            LinkedList_To_BST_Node rightNode = _BuildTreeRecur1(n - n / 2 - 1);

            root.Left  = leftNode;
            root.Right = rightNode;

            return(root);
        }
        private static LinkedList_To_BST_Node _BuildTreeRecur2(int startN, int endN)
        {
            if (startN == endN)
            {
                return(new LinkedList_To_BST_Node(_FindNthNode(startN).Value));
            }

            if (startN > endN)
            {
                return(null);
            }

            LinkedList_To_BST_Node leftNode  = _BuildTreeRecur2(startN, (startN + endN) / 2 - 1);
            LinkedList_To_BST_Node rightNode = _BuildTreeRecur2((startN + endN) / 2 + 1, endN);

            LinkedList_To_BST_Node root = new LinkedList_To_BST_Node(_FindNthNode((startN + endN) / 2).Value);

            root.Left  = leftNode;
            root.Right = rightNode;

            return(root);
        }