public static int CalculateHeight(BstItem tree) { if (tree == null) { return -1; } int leftHeight = CalculateHeight(tree.Left); int rightHeight = CalculateHeight(tree.Right); return 1 + (leftHeight > rightHeight ? leftHeight : rightHeight); }
/// <summary> /// Позволяет выбрать сортированный по возрастанию массив ключей /// </summary> public static void CrossTraverseRecursive(BstItem node, Action<BstItem> visit) { if (node == null) { return; } CrossTraverseRecursive(node.Left, visit); visit(node); CrossTraverseRecursive(node.Right, visit); }
/// <summary> /// Нерекурсивный прямой обход. /// </summary> public static void DirectTraverseNonRecursive(BstItem node, Action<BstItem> visit) { Stack<BstItem> stack = new Stack<BstItem>(); stack.Push(node); while (stack.Count != 0) { BstItem item = stack.Pop(); visit(item); if (item.Left != null) stack.Push(item.Left); if (item.Right != null) stack.Push(item.Right); } }
/// <summary> /// Поиск в бинарном дереве /// </summary> public static Item SearchBst(BstItem 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); }
private static void InsertRecursive(ref BstItem tree, Item item, int digit) { if (tree == null) { tree = new BstItem(item); return; } if (BstTreeUtils.DigitBit(item.Key, digit)) // текущий бит ключа 1 { InsertRecursive(ref tree.Right, item, digit+1); } else // текущий бит ключа 0 { InsertRecursive(ref tree.Left, item, digit + 1); } }
private static void InsertRecursive(ref BstItem tree, Item item, int digit) { if (tree == null) { tree = new BstItem(item); return; } if (BstTreeUtils.DigitBit(item.Key, digit)) // текущий бит ключа 1 { InsertRecursive(ref tree.Right, item, digit + 1); } else // текущий бит ключа 0 { InsertRecursive(ref tree.Left, item, digit + 1); } }
private void InsertBstNonRecursive(ref BstItem tree, Item item) { if (tree == null) { tree = new BstItem(item); } BstItem p = tree; for (BstItem q = p; q != null; p = q == null ? p : q) { q = item < p.Item ? p.Left : p.Right; } // нашли парент if (item < p.Item) { p.Left = new BstItem(item); } else { p.Right = new BstItem(item); } }
private Item SearchDstRecursive(BstItem tree, int key, int digit) { // следуем по дереву, заданному битами ИСКОМОГО/ВСТАВЛЯЕМОГО ключа if (tree == null) { return null; } if (tree.Item.Key == key) { return tree.Item; } if (BstTreeUtils.DigitBit(key, digit)) // current bit is 1 { return SearchDstRecursive(tree.Right, key, digit + 1); } else // current bit is 0 { return SearchDstRecursive(tree.Left, key, digit + 1); } }
private Item SearchDstRecursive(BstItem tree, int key, int digit) { // следуем по дереву, заданному битами ИСКОМОГО/ВСТАВЛЯЕМОГО ключа if (tree == null) { return(null); } if (tree.Item.Key == key) { return(tree.Item); } if (BstTreeUtils.DigitBit(key, digit)) // current bit is 1 { return(SearchDstRecursive(tree.Right, key, digit + 1)); } else // current bit is 0 { return(SearchDstRecursive(tree.Left, key, digit + 1)); } }
private void InsertBstRecursive(ref BstItem tree, Item item) { if (tree == null) { tree = new BstItem(item) { Left = null, Right = null }; } else { if (tree.Item > item) { InsertBstRecursive(ref tree.Left, item); } else { InsertBstRecursive(ref tree.Right, item); } } }
/// <summary> /// Вставка в корень - рекурсивеая реализация /// </summary> public static void InsertIntoRoot(ref BstItem root, Item item) { if (root == null) { root = new BstItem(item); return; } if (item < root.Item) { InsertIntoRoot(ref root.Left, item); RotateRight(ref root); } else { InsertIntoRoot(ref root.Right, item); RotateLeft(ref root); } }
/// <summary> /// Поворот налево. /// Узел становится левым дочерним узлом своего правого дочернего узла /// </summary> public static void RotateLeft(ref BstItem a) { BstItem x = a.Right; a.Right = x.Left; x.Left = a; a = x; }
/// <summary> /// Сосчитать узлы в дереве /// </summary> public static int GetNodesCount(BstItem root) { if (root == null) { return 0; } return 1 + GetNodesCount(root.Left) + GetNodesCount(root.Right); }
/// <summary> /// Рекурсивная выборка. /// Возвращается k-й наименьший элемент. /// </summary> public static Item SelectRecursive(BstItem tree, int k) { if (tree == null) { return null; } int t = GetNodesCount(tree.Left); if (t > k) { SelectRecursive(tree.Left, k); } else if (t < k) { SelectRecursive(tree.Right, k - t - 1); } return tree.Item; }
/// <summary> /// Нерекурсивная выборка. /// Возвращается k-й наименьший элемент. /// </summary> public static Item SelectNonRecursive(BstItem tree, int k) { if (tree == null) { return null; } int k1 = k; BstItem item = tree; int c; while ((c = GetNodesCount(item.Left)) != k1) { if (c > k1) { item = item.Left; } else if (c < k1) { k1 = k1 - c - 1; item = item.Right; } } return item.Item; }
/// <summary> /// Разбиение BST-дерева. /// k-й наименьший элемент попадёт в корень. /// </summary> public static void PartitionRecursive(ref BstItem tree, int k) { // сколько у нас в левом поддереве? int t = tree.Left == null ? 0 : GetNodesCount(tree.Left); if (t > k) // новый корень - в левом поддереве { PartitionRecursive(ref tree.Left, k); RotateRight(ref tree); } else if (t < k) // новый корень - в правом поддереве { PartitionRecursive(ref tree.Right, k-t-1); RotateLeft(ref tree); } // иначе - разбиение уже изначально было верным }
/// <summary> /// Удаляем из бинарного дерева корень. /// </summary> /// <param name="tree"></param> public static void RemoveRoot(ref BstItem tree) { tree = Join(ref tree.Left, ref tree.Right); }
/// <summary> /// Обход по уровням, на каждом уровне сохраняем значение уровня для каждого элемента /// Посещая элемент, инкрементим общий счётчик на уровень этого элемента. /// </summary> public static int CalculateInternalPathLength(BstItem node) { int result = 0; Queue<LeveledBstItem> queue = new Queue<LeveledBstItem>(); queue.Enqueue(new LeveledBstItem(node, 0)); while (queue.Count != 0) { LeveledBstItem item = queue.Dequeue(); result += item.Level; if (item.Item.Left != null) queue. Enqueue(new LeveledBstItem(item.Item.Left, item.Level + 1)); if (item.Item.Right != null) queue. Enqueue(new LeveledBstItem(item.Item.Right, item.Level + 1)); } return result; }
/// <summary> /// Удаляем из бинарного дерева элемент с заданным ключом. /// </summary> public static void RemoveRecursive(ref BstItem tree, int key) { if (tree == null) { return; // не нашли такого элемента } if (key < tree.Item.Key) // ищем в левом деревк { RemoveRecursive(ref tree.Left, key); } if (key > tree.Item.Key) // ищем в правом дереве { RemoveRecursive(ref tree.Right, key); } if (key == tree.Item.Key) // нашли, удаляем, объединяя левое и правое поддеревья { tree = Join(ref tree.Left, ref tree.Right); } }
/// <summary> /// Объединение двух бинарных деревьев. /// </summary> public static BstItem Join(ref BstItem left, ref BstItem right) { if (right == null) { return left; } PartitionRecursive(ref right, 0); right.Left = left; return right; }
/// <summary> /// Поворот направо. /// Узел становится правым дочерним узлом своего левого дочернего узла /// </summary> public static void RotateRight(ref BstItem a) { BstItem left = a.Left; a.Left = left.Right; left.Right = a; a = left; }
public LeveledBstItem(BstItem node, int level) { Item = node; Level = level; }