/// <summary>
 /// Сосчитать узлы в красно-чёрном дереве
 /// </summary>
 public static int GetNodesCount(RbItem root)
 {
     if (root == null)
     {
         return(0);
     }
     return(1 + GetNodesCount(root.Left) + GetNodesCount(root.Right));
 }
        /// <summary>
        /// Поворот узла вправо для красно-чёрного дерева.
        /// </summary>
        /// <param name="a"></param>
        public static void RotateRight(ref RbItem a)
        {
            RbItem left = a.Left;

            a.Left     = left.Right;
            left.Right = a;
            a          = left;
        }
        /// <summary>
        /// Поворот налево  в красно-чёрном дереве.
        /// Узел становится левым дочерним узлом своего правого дочернего узла
        /// </summary>
        public static void RotateLeft(ref RbItem a)
        {
            RbItem x = a.Right;

            a.Right = x.Left;
            x.Left  = a;
            a       = x;
        }
 /// <summary>
 /// Поиск в бинарном дереве
 /// </summary>
 public static Item SearchBst(RbItem tree, int key)
 {
     if (tree.Item.Key == key)
     {
         return(tree.Item);
     }
     if (key < tree.Item.Key)
     {
         return(SearchBst(tree.Left, key));
     }
     return(SearchBst(tree.Right, key));
 }
 /// <summary>
 /// Поиск в бинарном дереве
 /// </summary>
 public static Item SearchBst(RbItem tree, int key)
 {
     if (tree.Item.Key == key)
     {
         return tree.Item;
     }
     if (key < tree.Item.Key)
     {
         return SearchBst(tree.Left, key);
     }
     return SearchBst(tree.Right, key);
 }
 /// <summary>
 /// Рекурсивная вставка в красно-чёрное дерево.
 /// </summary>
 /// <param name="root"></param>
 /// <param name="item"></param>
 /// <param name="sw">Если на предыдущем уровне вставка была влево, то False, если в правое дерево, то True.</param>
 private static void Insert(ref RbItem root, Item item, bool sw)
 {
     if (root == null)
     {
         // если дерево пустое то вставляем новый чёрный элемент (не часть 3- или 4-элемента)
         root = new RbItem(item);
         return;
     }
     // разбиваем на рекурсивном спуске, если это 4-узел
     if (IsRed(root.Left) && IsRed(root.Right))
     {
         // перекрашиваем
         root.Left.IsRed = false;
         root.Right.IsRed = false;
         root.IsRed = true;
     }
     // рекурсивная вставка в правое или в левое поддерево
     if (item < root.Item)
     {
         // вставляем в левое поддерево
         Insert(ref root.Left, item, false);
         // ротации на подъёме
         if (root.IsRed && root.Left.IsRed && sw) // две однонаправленные последовательные красные ссылки
         {
             BstTreeUtils.RotateRight(ref root);
         }
         if (root.Left.IsRed && root.Left.Left.IsRed) // две однонаправленные последовательные красные ссылки уровнем ниже
         {
             BstTreeUtils.RotateRight(ref root);
             root.IsRed = false;
             root.Right.IsRed = true;
         }
     }
     else
     {
         // вставляем в правое поддерево
         Insert(ref root.Right, item, true);
         // ротации на подъёме
         if (root.IsRed && root.Right.IsRed && !sw)
         {
             BstTreeUtils.RotateLeft(ref root);
         }
         if (root.Right.IsRed && root.Right.Right.IsRed)
         {
             BstTreeUtils.RotateLeft(ref root);
             root.IsRed = false;
             root.Left.IsRed = true; // сделали нормальный 4-узел
         }
     }
 }
 private static bool IsRed(RbItem item)
 {
     return item != null && item.IsRed;
 }
 /// <summary>
 /// Удаление из красно-чёрного дерева.
 /// </summary>
 public static void Remove(ref RbItem tree, int key)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Удаление из красно-чёрного дерева.
 /// </summary>
 public static void Remove(ref RbItem tree, int key)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Сосчитать узлы в красно-чёрном дереве
 /// </summary>
 public static int GetNodesCount(RbItem root)
 {
     if (root == null)
     {
         return 0;
     }
     return 1 + GetNodesCount(root.Left) + GetNodesCount(root.Right);
 }
 /// <summary>
 /// Поворот налево  в красно-чёрном дереве.
 /// Узел становится левым дочерним узлом своего правого дочернего узла
 /// </summary>
 public static void RotateLeft(ref RbItem a)
 {
     RbItem x = a.Right;
     a.Right = x.Left;
     x.Left = a;
     a = x;
 }
 /// <summary>
 /// Поворот узла вправо для красно-чёрного дерева.
 /// </summary>
 /// <param name="a"></param>
 public static void RotateRight(ref RbItem a)
 {
     RbItem left = a.Left;
     a.Left = left.Right;
     left.Right = a;
     a = left;
 }