/// <summary>
 /// Добавление элемента в БДП
 /// </summary>
 /// <param name="node"></param>
 /// <param name="parent"></param>
 private void Insert(BST_Node node, ref BST_Node parent)
 {
     if (parent == null)
     {
         parent = node;
     }
     else
     {
         if (node.Value.CompareTo(parent.Value) < 0)
         {
             //BST_Node A = (BST_Node)parent.Left;
             Insert(node, ref parent.Left);
         }
         else if (node.Value.CompareTo(parent.Value) > 0)
         {
             //BST_Node A = (BST_Node)parent.Right;
             Insert(node, ref parent.Right);
         }
         else if (node.Value.CompareTo(parent.Value) == 0)
         {
             throw new ArgumentException("Операция невозможна - такой элемент" +
                                         " в дереве уже существует");
         }
     }
 }
        /// <summary>
        /// Вставка элемента в дерево
        /// </summary>
        /// <param name="value"></param>
        public void Insert(int value)
        {
            BST_Node node = new BST_Node(value);

            Insert(node);
            BalanceTree();
        }
 /// <summary>
 /// Заполнение <see cref = "ICollection{BST_Node}"/> в порядке LCR
 /// </summary>
 /// <param name="node"></param>
 /// <param name="list"></param>
 public static void FillListInOrder(BST_Node node, ICollection <BST_Node> list)
 {
     if (node != null)
     {
         FillListInOrder((BST_Node)node.Left, list);
         list.Add(node);
         FillListInOrder((BST_Node)node.Right, list);
     }
 }
        /// <summary>
        /// Балнсировка дерева
        /// </summary>
        public void BalanceTree()
        {
            List <BST_Node> listOfNodes = new List <BST_Node>();

            FillListInOrder(Root, listOfNodes);
            RemoveChildren(listOfNodes);
            Root = null;
            int count = Count;

            Count = 0;
            BalanceTree(0, count - 1, listOfNodes);
        }
 private IEnumerable <BST_Node> PostOrder(BST_Node node)
 {
     if (node != null)
     {
         foreach (BST_Node left in PostOrder((BST_Node)node.Left))
         {
             yield return(left);
         }
         foreach (BST_Node right in PostOrder((BST_Node)node.Right))
         {
             yield return(right);
         }
         yield return(node);
     }
 }
        public IEnumerable <BST_Node> BreadthFirstTraversal()
        {
            Queue <BST_Node> queue = new Queue <BST_Node>();

            queue.Enqueue(Root);
            while (queue.Count != 0)
            {
                BST_Node current = queue.Dequeue();
                if (current != null)
                {
                    queue.Enqueue((BST_Node)current.Left);
                    queue.Enqueue((BST_Node)current.Right);
                    yield return(current);
                }
            }
        }
 private void Insert(BST_Node node)
 {
     if (node == null)
     {
         throw new ArgumentNullException
                   ("node", "Попытка вставки пустого узла (null)");
     }
     if (Root == null)
     {
         Root = node;
     }
     else
     {
         Insert(node, ref Root);
     }
     Count++;
 }
        private BST_Node FindLeftMost(BST_Node node, bool setParentToNull)
        {
            BST_Node leftMost = null;
            BST_Node current  = leftMost = node;
            BST_Node parent   = null;

            while (current != null)
            {
                if (current.Left != null)
                {
                    parent   = current;
                    leftMost = (BST_Node)current.Left;
                }
                current = (BST_Node)current.Left;
            }
            if (parent != null && setParentToNull)
            {
                parent.Left = null;
            }
            return(leftMost);
        }
        /// <summary>
        /// Поиск  элемента в дереве
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public BST_Node Search(int value)
        {
            BST_Node tree = Root;

            while (Root != null)
            {
                if (value.CompareTo(tree.Value) == 0)
                {
                    return(tree);
                }
                else if (value.CompareTo(tree.Value) < 0)
                {
                    tree = (BST_Node)tree.Left;
                }
                else if (value.CompareTo(tree.Value) > 0)
                {
                    tree = (BST_Node)tree.Right;
                }
            }
            return(null);
        }
        /// <summary>
        /// Удаление элемента из дерева
        /// </summary>
        /// <param name="value"></param>
        /// <param name="rebalanceTree"></param>
        public void Delete(int value)
        {
            bool     rebalanceTree = true;
            BST_Node parentNode;
            BST_Node foundNode = null;
            BST_Node tree      = parentNode = Root;

            //Поиск узла с сохранением ссылки на родителя
            while (tree != null)
            {
                if (value.CompareTo(tree.Value) == 0)
                {
                    foundNode = tree;
                    break;
                }
                else if (value.CompareTo(tree.Value) < 0)
                {
                    parentNode = tree;
                    tree       = (BST_Node)tree.Left;
                }
                else if (value.CompareTo(tree.Value) > 0)
                {
                    parentNode = tree;
                    tree       = (BST_Node)tree.Right;
                }
            }
            if (foundNode == null)
            {
                throw new ArgumentException("Элемент не найден");
            }
            bool leftOrRightNode = false;

            if (foundNode != parentNode.Left)
            {
                leftOrRightNode = true;
            }
            if (foundNode == parentNode) //Удаление корня
            {
                if (rebalanceTree)
                {
                    List <BST_Node> listOfNodes = new List <BST_Node>();
                    FillListInOrder(Root, listOfNodes);
                    RemoveChildren(listOfNodes);
                    listOfNodes.Remove(parentNode);
                    Root = null;
                    int count = Count - 1;
                    Count = 0;
                    BalanceTree(0, count - 1, listOfNodes);
                }
                else
                {
                    // Обычный способ без балансировки - просто ищется самый левый узел
                    // с правой стороны дерева, и делается корневым
                    BST_Node leftMost = FindLeftMost((BST_Node)parentNode.Right, true);
                    if (leftMost != null)
                    {
                        leftMost.Left  = parentNode.Left;
                        leftMost.Right = parentNode.Right;
                        Root           = leftMost;
                    }
                }
            }
            //Если это "лист"
            else if (foundNode.Left == null && foundNode.Right == null)
            {
                if (leftOrRightNode)
                {
                    parentNode.Right = null;
                }
                else
                {
                    parentNode.Left = null;
                }
            }
            // Если это обычный узелс 2-мя потомками
            else if (foundNode.Left != null && foundNode.Right != null)
            {
                if (leftOrRightNode)
                {
                    parentNode.Right      = foundNode.Right;
                    parentNode.Right.Left = foundNode.Left;
                }
                else
                {
                    parentNode.Left      = foundNode.Right;
                    parentNode.Left.Left = foundNode.Left;
                }
            }
            // Если это узел с 1 потомком
            else if (foundNode.Left != null || foundNode.Right != null)
            {
                // Если потомок левый
                if (foundNode.Left != null)
                {
                    if (leftOrRightNode)
                    {
                        parentNode.Right = foundNode.Left;
                    }
                    else
                    {
                        parentNode.Left = foundNode.Left;
                    }
                }
                // Если потомок правый
                else
                {
                    if (leftOrRightNode)
                    {
                        parentNode.Right = foundNode.Right;
                    }
                    else
                    {
                        parentNode.Left = foundNode.Right;
                    }
                }
            }
            if (foundNode != parentNode)
            {
                Count--;
                BalanceTree();
            }
        }