/// <summary>
 /// Сосчитать узлы в дереве
 /// </summary>
 public static int GetNodesCount(BstItem root)
 {
     if (root == null)
     {
         return(0);
     }
     return(1 + GetNodesCount(root.Left) + GetNodesCount(root.Right));
 }
        /// <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 void RotateRight(ref BstItem a)
        {
            BstItem left = a.Left;

            a.Left     = left.Right;
            left.Right = a;
            a          = left;
        }
 /// <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 BstItem Join(ref BstItem left, ref BstItem right)
 {
     if (right == null)
     {
         return(left);
     }
     PartitionRecursive(ref right, 0);
     right.Left = left;
     return(right);
 }
        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 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));
 }
        /// <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>
        /// Рекурсивная выборка.
        /// Возвращается 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);
        }
Beispiel #10
0
 /// <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);
     }
 }
Beispiel #11
0
        /// <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);
                }
            }
        }
Beispiel #12
0
 /// <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);
     }
 }
Beispiel #13
0
        /// <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);
        }
Beispiel #14
0
        /// <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);
        }
Beispiel #15
0
 public LeveledBstItem(BstItem node, int level)
 {
     Item  = node;
     Level = level;
 }
Beispiel #16
0
 /// <summary>
 /// Удаляем из бинарного дерева корень.
 /// </summary>
 /// <param name="tree"></param>
 public static void RemoveRoot(ref BstItem tree)
 {
     tree = Join(ref tree.Left, ref tree.Right);
 }