/// <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 int GetNodesCount(RbItem root) { if (root == null) { return 0; } return 1 + GetNodesCount(root.Left) + GetNodesCount(root.Right); }