예제 #1
0
        internal T Get(Node node, CompareToKnownValue <T> compare)
        {
            int loc = 0;

            for (int i = 0; i < node.ItemCount; i++)
            {
                switch (compare(node.Items[i]))
                {
                case Less:
                    loc++;
                    continue;

                case Equal:
                    goto break_for;

                case Greater:
                    goto break_for;

                default:
                    throw new NotImplementedException();
                }
            }
break_for:
            if (loc < node.ItemCount && compare(node.Items[loc]) == Equal)
            {
                return(node.Items[loc]);
            }
            if (node.ChildCount == 0)
            {
                throw new InvalidOperationException("getting a non-existing item");
            }
            return(this.Get(node.Children[loc], compare));
        }
예제 #2
0
        private static int Binary <T>(GetIndex <T> get, int index, int length, CompareToKnownValue <T> compare)
        {
            int low = index;
            int hi  = index + length - 1;

            while (low <= hi)
            {
                int median = low + (hi - low >> 1);
                switch (compare(get(median)))
                {
                case CompareResult.Equal:
                    return(median);

                case CompareResult.Less:
                    low = median + 1;
                    break;

                case CompareResult.Greater:
                    hi = median - 1;
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
            return(~low);
        }
예제 #3
0
        internal void Remove(Node node, CompareToKnownValue <T> compare)
        {
            int loc = 0;

            for (int i = 0; i < node.ItemCount; i++)
            {
                switch (compare(node.Items[i]))
                {
                case Less:
                    loc++;
                    continue;

                case Equal:
                    goto break_for;

                case Greater:
                    goto break_for;

                default:
                    throw new System.NotImplementedException();
                }
            }
break_for:
            if (loc < node.ItemCount && compare(node.Items[loc]) == Equal)
            {
                RemoveKeyFromNode(node, compare, loc);
                return;
            }
            if (!(node.ChildCount == 0))
            {
                RemoveKeyFromSubtree(node, compare, loc);
            }
        }
예제 #4
0
        /// <summary>Tries to remove a value.</summary>
        /// <param name="compare">The compare delegate.</param>
        /// <param name="exception">The exception that occurred if the remove failed.</param>
        /// <returns>True if the remove was successful or false if not.</returns>
        public bool TryRemove(CompareToKnownValue <T> compare, out Exception exception)
        {
            Node node;

            node = _root;
            while (node != _sentinelNode)
            {
                CompareResult compareResult = compare(node.Value);
                if (compareResult == Less)
                {
                    node = node.LeftChild;
                }
                else if (compareResult == Greater)
                {
                    node = node.RightChild;
                }
                else                 // (compareResult == Equal)
                {
                    if (node == _sentinelNode)
                    {
                        exception = new ArgumentException("Attempting to remove a non-existing entry.");
                        return(false);
                    }
                    Remove(node);
                    _count   -= 1;
                    exception = null;
                    return(true);
                }
            }
            exception = new ArgumentException("Attempting to remove a non-existing entry.");
            return(false);
        }
예제 #5
0
파일: AvlTree.cs 프로젝트: Thaina/Towel
        /// <summary>Tries to get a value.</summary>
        /// <param name="compare">The compare delegate.</param>
        /// <param name="value">The value if found or default.</param>
        /// <param name="exception">The exception that occurred if the get failed.</param>
        /// <returns>True if the get succeeded or false if not.</returns>
        /// <runtime>O(ln(Count)) Ω(1)</runtime>
        public bool TryGet(CompareToKnownValue <T> compare, out T value, out Exception exception)
        {
            Node node = _root;

            while (node != null)
            {
                CompareResult comparison = compare(node.Value);
                if (comparison == Less)
                {
                    node = node.LeftChild;
                }
                else if (comparison == Greater)
                {
                    node = node.RightChild;
                }
                else                 // (compareResult == Copmarison.Equal)
                {
                    value     = node.Value;
                    exception = null;
                    return(true);
                }
            }
            value     = default;
            exception = new InvalidOperationException("Attempting to get a non-existing value from an AVL tree.");
            return(false);
        }
예제 #6
0
        /// <summary>Tries to get a value.</summary>
        /// <param name="compare">The compare delegate.</param>
        /// <param name="value">The value if it was found or default.</param>
        /// <param name="exception">The exception that occurred if the get failed.</param>
        /// <returns>True if the value was found or false if not.</returns>
        public bool TryGet(CompareToKnownValue <T> compare, out T value, out Exception exception)
        {
            Node treeNode = _root;

            while (treeNode != _sentinelNode)
            {
                CompareResult compareResult = compare(treeNode.Value);
                if (compareResult == Greater)
                {
                    treeNode = treeNode.RightChild;
                }
                else if (compareResult == Less)
                {
                    treeNode = treeNode.LeftChild;
                }
                else
                {
                    value     = treeNode.Value;
                    exception = null;
                    return(true);
                }
            }
            value     = default;
            exception = new ArgumentException("Attempting to get a non-existing value.");
            return(false);
        }
예제 #7
0
        /// <summary>Determines if this structure contains an item by a given key.</summary>
        /// <param name="compare">The sorting technique (must synchronize with this structure's sorting).</param>
        /// <returns>True of contained, False if not.</returns>
        /// <runtime>O(ln(Count)) Ω(1)</runtime>
        public bool Contains(CompareToKnownValue <T> compare)
        {
            Node treeNode = _root;

            while (treeNode != _sentinelNode)
            {
                switch (compare(treeNode.Value))
                {
                case Equal:
                    return(true);

                case Greater:
                    treeNode = treeNode.RightChild;
                    break;

                case Less:
                    treeNode = treeNode.LeftChild;
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
            return(false);
        }
예제 #8
0
 /// <summary>Removes a value.</summary>
 /// <typeparam name="T">The type of value.</typeparam>
 /// <param name="tree">The tree to remove the value from.</param>
 /// <param name="compare">The compare delegate.</param>
 public static void Remove <T>(this ISortedBinaryTree <T> tree, CompareToKnownValue <T> compare)
 {
     if (!tree.TryRemove(compare, out Exception exception))
     {
         throw exception;
     }
 }
예제 #9
0
        // methods (internal)
        #region internal bool Contains<K>(Node node, K key, Compare<T, K> compare)
        internal bool Contains(Node node, CompareToKnownValue <T> compare)
        {
            int loc = 0;

            for (int i = 0; i < node.ItemCount; i++)
            {
                switch (compare(node.Items[i]))
                {
                case Less:
                    loc++;
                    continue;

                case Equal:
                    goto break_for;

                case Greater:
                    goto break_for;

                default:
                    throw new System.NotImplementedException();
                }
            }
break_for:
            if (loc < node.ItemCount && compare(node.Items[loc]) == Equal)
            {
                return(true);
            }
            if (node.ChildCount == 0)
            {
                return(false);
            }
            return(this.Contains(node.Children[loc], compare));
        }
예제 #10
0
파일: Search.cs 프로젝트: pfriesch/Towel
        internal static int Binary <T>(GetIndex <T> get, int index, int length, CompareToKnownValue <T> compare)
        {
            int low = index;
            int hi  = index + length - 1;

            while (low <= hi)
            {
                int           median        = low + (hi - low >> 1);
                CompareResult compareResult = compare(get(median));
                if (compareResult is Less)
                {
                    low = median + 1;
                }
                else if (compareResult is Greater)
                {
                    hi = median - 1;
                }
                else if (compareResult is Equal)
                {
                    return(median);
                }
                else
                {
                    throw new TowelBugException("Unhandled CompareResult.");
                }
            }
            return(~low);
        }
예제 #11
0
 /// <summary>Gets a value.</summary>
 /// <typeparam name="T">The type of value.</typeparam>
 /// <param name="tree">The tree to get the value from.</param>
 /// <param name="compare">The compare delegate. This must match the compare that the Red-Black tree is sorted with.</param>
 /// <returns>The value.</returns>
 public static T Get <T>(this ISortedBinaryTree <T> tree, CompareToKnownValue <T> compare)
 {
     if (!tree.TryGet(compare, out T value, out Exception exception))
     {
         throw exception;
     }
     return(value);
 }
예제 #12
0
파일: Search.cs 프로젝트: pfriesch/Towel
 /// <summary>Performs a binary search to find the index where a specific value fits in indexed, sorted items.</summary>
 /// <typeparam name="T">The generic type of the set of values.</typeparam>
 /// <param name="get">Indexer delegate.</param>
 /// <param name="length">The number of indexed items.</param>
 /// <param name="compare">Comparison delegate.</param>
 /// <returns>The index where the specific value fits into the index, sorted items.</returns>
 public static int Binary <T>(GetIndex <T> get, int length, CompareToKnownValue <T> compare)
 {
     _ = get ?? throw new ArgumentNullException(nameof(get));
     _ = compare ?? throw new ArgumentNullException(nameof(compare));
     if (length <= 0)
     {
         throw new ArgumentOutOfRangeException(nameof(length), length, "!(" + nameof(length) + " > 0)");
     }
     return(Binary(get, 0, length, compare));
 }
예제 #13
0
        internal void RemoveKeyFromSubtree(Node parentNode, CompareToKnownValue <T> compare, int subtreeIndexInNode)
        {
            Node childNode = parentNode.Children[subtreeIndexInNode];

            if (childNode.ItemCount == _node_size - 1)
            {
                int  leftIndex   = subtreeIndexInNode - 1;
                Node leftSibling = subtreeIndexInNode > 0 ? parentNode.Children[leftIndex] : null;

                int  rightIndex   = subtreeIndexInNode + 1;
                Node rightSibling = subtreeIndexInNode < parentNode.ChildCount - 1 ? parentNode.Children[rightIndex] : null;

                if (leftSibling is not null && leftSibling.ItemCount > _node_size - 1)
                {
                    for (int i = childNode.ChildCount; i > -1; i--)
                    {
                        childNode.Items[i] = childNode.Items[i - 1];
                    }
                    childNode.Items[0] = parentNode.Items[subtreeIndexInNode];
                    childNode.ItemCount++;
                    parentNode.Items[subtreeIndexInNode] = leftSibling.Items[leftSibling.ItemCount - 1];
                    leftSibling.ItemCount--;

                    if (!(leftSibling.ChildCount == 0))
                    {
                        for (int i = childNode.ChildCount; i > -1; i--)
                        {
                            childNode.Children[i] = childNode.Children[i - 1];
                        }
                        childNode.Children[0] = leftSibling.Children[leftSibling.ChildCount - 1];
                        leftSibling.ChildCount--;
                    }
                }
                else if (rightSibling is not null && rightSibling.ItemCount > _node_size - 1)
                {
                    childNode.Items[childNode.ItemCount] = parentNode.Items[subtreeIndexInNode];
                    childNode.ItemCount++;
                    parentNode.Items[subtreeIndexInNode] = rightSibling.Items[0];
                    for (int i = 0; i < rightSibling.ItemCount; i++)
                    {
                        rightSibling.Items[i] = rightSibling.Items[i + 1];
                    }
                    rightSibling.ItemCount--;

                    if (!(rightSibling.ChildCount == 0))
                    {
                        childNode.Children[childNode.ChildCount - 1] = rightSibling.Children[0];
                        childNode.ChildCount++;
                        for (int i = 0; i < rightSibling.ChildCount; i++)
                        {
                            rightSibling.Items[i] = rightSibling.Items[i + 1];
                        }
                        rightSibling.ChildCount--;
                    }
                }
예제 #14
0
 /// <summary>Wrapper for the remove function to handle exceptions.</summary>
 /// <typeparam name="T">The generic type of this data structure.</typeparam>
 /// <param name="avlTree">This structure.</param>
 /// <param name="compare">The sorting technique (must synchronize with this structure's sorting).</param>
 /// <returns>True if successful, False if not.</returns>
 public static bool TryRemove <T>(this IAvlTree <T> avlTree, CompareToKnownValue <T> compare)
 {
     try
     {
         avlTree.Remove(compare);
         return(true);
     }
     catch
     {
         return(false);
     }
 }
예제 #15
0
        internal void RemoveKeyFromNode(Node node, CompareToKnownValue <T> compare, int keyIndexInNode)
        {
            if (node.ChildCount == 0)
            {
                for (int i = keyIndexInNode; i < node.ItemCount; i++)
                {
                    node.Items[i] = node.Items[i + 1];
                }
                node.ItemCount--;
                return;
            }

            Node predecessorChild = node.Children[keyIndexInNode];

            if (predecessorChild.ItemCount >= _node_size)
            {
                T predecessor = RemovePredecessor(predecessorChild);
                node.Items[keyIndexInNode] = predecessor;
            }
            else
            {
                Node successorChild = node.Children[keyIndexInNode + 1];
                if (successorChild.ItemCount >= _node_size)
                {
                    T successor = RemoveSuccessor(predecessorChild);
                    node.Items[keyIndexInNode] = successor;
                }
                else
                {
                    predecessorChild.Items[predecessorChild.ItemCount++] = node.Items[keyIndexInNode];
                    for (int i = 0; i < successorChild.ItemCount; i++)
                    {
                        predecessorChild.Items[predecessorChild.ItemCount++] = successorChild.Items[i];
                    }
                    for (int i = 0; i < successorChild.ChildCount; i++)
                    {
                        predecessorChild.Items[predecessorChild.ChildCount++] = successorChild.Items[i];
                    }
                    for (int i = keyIndexInNode; i < node.ItemCount; i++)
                    {
                        node.Items[i] = node.Items[i + 1];
                    }
                    node.ItemCount--;
                    for (int i = keyIndexInNode + 1; i < node.ChildCount; i++)
                    {
                        node.Children[i] = node.Children[i + 1];
                    }
                    node.ChildCount--;
                    Remove(predecessorChild, compare);
                }
            }
        }
예제 #16
0
 /// <summary>Wrapper for the get function to handle exceptions.</summary>
 /// <typeparam name="T">The generic type of this data structure.</typeparam>
 /// <param name="avlTree">This structure.</param>
 /// <param name="compare">The sorting technique (must synchronize with this structure's sorting).</param>
 /// <param name="item">The item if found.</param>
 /// <returns>True if successful, False if not.</returns>
 public static bool TryGet <T>(this IAvlTree <T> avlTree, CompareToKnownValue <T> compare, out T item)
 {
     try
     {
         item = avlTree.Get(compare);
         return(true);
     }
     catch
     {
         item = default(T);
         return(false);
     }
 }
예제 #17
0
파일: AvlTree.cs 프로젝트: Thaina/Towel
        /// <summary>Tries to remove a value.</summary>
        /// <param name="compare">The compare delegate.</param>
        /// <param name="exception">The exception that occurred if the remove failed.</param>
        /// <returns>True if the remove was successful or false if not.</returns>
        public bool TryRemove(CompareToKnownValue <T> compare, out Exception exception)
        {
            Exception capturedException = null;

            Node Remove(Node node)
            {
                if (node != null)
                {
                    CompareResult compareResult = compare(node.Value);
                    if (compareResult == Less)
                    {
                        node.RightChild = Remove(node.RightChild);
                    }
                    else if (compareResult == Greater)
                    {
                        node.LeftChild = Remove(node.LeftChild);
                    }
                    else                     // (compareResult == Comparison.Equal)
                    {
                        if (node.RightChild != null)
                        {
                            node.RightChild            = RemoveLeftMost(node.RightChild, out Node leftMostOfRight);
                            leftMostOfRight.RightChild = node.RightChild;
                            leftMostOfRight.LeftChild  = node.LeftChild;
                            node = leftMostOfRight;
                        }
                        else if (node.LeftChild != null)
                        {
                            node.LeftChild             = RemoveRightMost(node.LeftChild, out Node rightMostOfLeft);
                            rightMostOfLeft.RightChild = node.RightChild;
                            rightMostOfLeft.LeftChild  = node.LeftChild;
                            node = rightMostOfLeft;
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    SetHeight(node);
                    return(Balance(node));
                }
                capturedException = new ArgumentException("Attempting to remove a non-existing entry.");
                return(node);
            }

            _root     = Remove(_root);
            exception = capturedException;
            _count--;
            return(exception is null);
        }
예제 #18
0
        /// <summary>Removes an item from the structure based on a key.</summary>
        /// <param name="compare">The compareison technique (must synchronize with this structure's sorting).</param>
        public void Remove(CompareToKnownValue <T> compare)
        {
            this.Remove(_root, compare);

            if (_root.ItemCount == 0 && !(_root.ChildCount == 0))
            {
                if (_root.ChildCount != 1)
                {
                    throw new System.InvalidOperationException("this._root.ChildCount != 1");
                }
                _root = _root.Children[0];
                _height--;
            }

            _count--;
        }
예제 #19
0
        /// <summary>Removes an item from this structure by a given key.</summary>
        /// <param name="compare">The sorting technique (must synchronize with the structure's sorting).</param>
        /// <runtime>O(ln(n))</runtime>
        public void Remove(CompareToKnownValue <T> compare)
        {
            Node REMOVE(CompareToKnownValue <T> COMPARE, Node NODE)
            {
                if (NODE != null)
                {
                    CompareResult compareResult = COMPARE(NODE.Value);
                    if (compareResult == CompareResult.Equal)
                    {
                        if (NODE.RightChild != null)
                        {
                            NODE.RightChild            = RemoveLeftMost(NODE.RightChild, out Node leftMostOfRight);
                            leftMostOfRight.RightChild = NODE.RightChild;
                            leftMostOfRight.LeftChild  = NODE.LeftChild;
                            NODE = leftMostOfRight;
                        }
                        else if (NODE.LeftChild != null)
                        {
                            NODE.LeftChild             = RemoveRightMost(NODE.LeftChild, out Node rightMostOfLeft);
                            rightMostOfLeft.RightChild = NODE.RightChild;
                            rightMostOfLeft.LeftChild  = NODE.LeftChild;
                            NODE = rightMostOfLeft;
                        }
                        else
                        {
                            return(null);
                        }
                        SetHeight(NODE);
                        return(Balance(NODE));
                    }
                    else if (compareResult == CompareResult.Greater)
                    {
                        NODE.LeftChild = REMOVE(COMPARE, NODE.LeftChild);
                    }
                    else // (compareResult == Comparison.Less)
                    {
                        NODE.RightChild = REMOVE(COMPARE, NODE.RightChild);
                    }
                    SetHeight(NODE);
                    return(Balance(NODE));
                }
                throw new InvalidOperationException("Attempting to remove a non-existing entry.");
            }

            _root = REMOVE(compare, _root);
            _count--;
        }
예제 #20
0
파일: AvlTree.cs 프로젝트: Thaina/Towel
        /// <summary>Determines if this structure contains an item by a given key.</summary>
        /// <param name="comparison">The sorting technique (must synchronize with this structure's sorting).</param>
        /// <returns>True of contained, False if not.</returns>
        /// <runtime>O(ln(Count)) Ω(1)</runtime>
        public bool Contains(CompareToKnownValue <T> comparison)
        {
            Node node = _root;

            while (node != null)
            {
                CompareResult compareResult = comparison(node.Value);
                if (compareResult == Less)
                {
                    node = node.LeftChild;
                }
                else if (compareResult == Greater)
                {
                    node = node.RightChild;
                }
                else                 // (compareResult == Copmarison.Equal)
                {
                    return(true);
                }
            }
            return(false);
        }
예제 #21
0
        /// <summary>Gets the item with the designated by the string.</summary>
        /// <param name="compare">The sorting technique (must synchronize with this structure's sorting).</param>
        /// <returns>The object with the desired string ID if it exists.</returns>
        /// <runtime>O(ln(Count)) Ω(1)</runtime>
        public T Get(CompareToKnownValue <T> compare)
        {
            Node node = _root;

            while (node != null)
            {
                CompareResult comparison = compare(node.Value);
                if (comparison == CompareResult.Equal)
                {
                    return(node.Value);
                }
                else if (comparison == CompareResult.Greater)
                {
                    node = node.LeftChild;
                }
                else // (compareResult == Copmarison.Less)
                {
                    node = node.RightChild;
                }
            }
            throw new InvalidOperationException("Attempting to get a non-existing item.");
        }
예제 #22
0
파일: Search.cs 프로젝트: pfriesch/Towel
 /// <summary>Performs a binary search to find the index where a specific value fits in indexed, sorted items.</summary>
 /// <typeparam name="T">The generic type of the set of values.</typeparam>
 /// <param name="array">The array to binary search on.</param>
 /// <param name="compare">Comparison delegate.</param>
 /// <returns>The index where the specific value fits into the index, sorted items.</returns>
 public static int Binary <T>(T[] array, CompareToKnownValue <T> compare) =>
 Binary(array.WrapGetIndex(), array.Length, compare);
예제 #23
0
 /// <summary>Tries to get a value.</summary>
 /// <typeparam name="T">The type of value.</typeparam>
 /// <param name="tree">The tree to get the value from.</param>
 /// <param name="compare">The compare delegate. This must match the compare that the Red-Black tree is sorted with.</param>
 /// <param name="value">The value if it is found.</param>
 /// <returns>True if the value was found or false if not.</returns>
 public static bool TryGet <T>(this ISortedBinaryTree <T> tree, CompareToKnownValue <T> compare, out T value) =>
 tree.TryGet(compare, out value, out _);
예제 #24
0
 /// <summary>Gets a value.</summary>
 /// <typeparam name="T">The type of value.</typeparam>
 /// <param name="tree">The tree to get the value from.</param>
 /// <param name="compare">The compare delegate. This must match the compare that the Red-Black tree is sorted with.</param>
 /// <returns>The value.</returns>
 public static T Get <T>(this ISortedBinaryTree <T> tree, CompareToKnownValue <T> compare) =>
 tree.TryGet(compare, out T value, out Exception exception)
예제 #25
0
 /// <summary>Tries to remove a value.</summary>
 /// <typeparam name="T">The type of value.</typeparam>
 /// <param name="tree">The tree to remove the value from.</param>
 /// <param name="compare">The compare delegate.</param>
 /// <returns>True if the remove was successful or false if not.</returns>
 public static bool TryRemove <T>(this ISortedBinaryTree <T> tree, CompareToKnownValue <T> compare)
 {
     return(tree.TryRemove(compare, out _));
 }
예제 #26
0
 /// <summary>Determines if this structure contains a given item based on a given key.</summary>
 /// <param name="compare">The sorting technique (must synchronize with the sorting of this structure).</param>
 /// <returns>True if found, False if not.</returns>
 public bool Contains(CompareToKnownValue <T> compare)
 {
     return(Contains(_root, compare));
 }
예제 #27
0
 /// <summary>Gets an item from this structure based on a given key.</summary>
 /// <param name="compare">The comparison techmique (must synchronize with this structure's sorting).</param>
 /// <returns>Item is found.</returns>
 public T Get(CompareToKnownValue <T> compare)
 {
     return(Get(_root, compare));
 }
예제 #28
0
        internal void RemoveKeyFromSubtree(Node parentNode, CompareToKnownValue <T> compare, int subtreeIndexInNode)
        {
            Node childNode = parentNode.Children[subtreeIndexInNode];

            if (childNode.ItemCount == _node_size - 1)
            {
                int  leftIndex   = subtreeIndexInNode - 1;
                Node leftSibling = subtreeIndexInNode > 0 ? parentNode.Children[leftIndex] : null;

                int  rightIndex   = subtreeIndexInNode + 1;
                Node rightSibling = subtreeIndexInNode < parentNode.ChildCount - 1 ? parentNode.Children[rightIndex] : null;

                if (leftSibling != null && leftSibling.ItemCount > _node_size - 1)
                {
                    for (int i = childNode.ChildCount; i > -1; i--)
                    {
                        childNode.Items[i] = childNode.Items[i - 1];
                    }
                    childNode.Items[0] = parentNode.Items[subtreeIndexInNode];
                    childNode.ItemCount++;
                    parentNode.Items[subtreeIndexInNode] = leftSibling.Items[leftSibling.ItemCount - 1];
                    leftSibling.ItemCount--;

                    if (!(leftSibling.ChildCount == 0))
                    {
                        for (int i = childNode.ChildCount; i > -1; i--)
                        {
                            childNode.Children[i] = childNode.Children[i - 1];
                        }
                        childNode.Children[0] = leftSibling.Children[leftSibling.ChildCount - 1];
                        leftSibling.ChildCount--;
                    }
                }
                else if (rightSibling != null && rightSibling.ItemCount > _node_size - 1)
                {
                    childNode.Items[childNode.ItemCount] = parentNode.Items[subtreeIndexInNode];
                    childNode.ItemCount++;
                    parentNode.Items[subtreeIndexInNode] = rightSibling.Items[0];
                    for (int i = 0; i < rightSibling.ItemCount; i++)
                    {
                        rightSibling.Items[i] = rightSibling.Items[i + 1];
                    }
                    rightSibling.ItemCount--;

                    if (!(rightSibling.ChildCount == 0))
                    {
                        childNode.Children[childNode.ChildCount - 1] = rightSibling.Children[0];
                        childNode.ChildCount++;
                        for (int i = 0; i < rightSibling.ChildCount; i++)
                        {
                            rightSibling.Items[i] = rightSibling.Items[i + 1];
                        }
                        rightSibling.ChildCount--;
                    }
                }
                else
                {
                    if (leftSibling != null)
                    {
                        for (int i = childNode.ItemCount; i > 0; i--)
                        {
                            childNode.Items[i] = childNode.Items[i - 1];
                        }
                        childNode.Items[0] = parentNode.Items[subtreeIndexInNode];
                        childNode.ItemCount++;

                        T[] oldEntries       = childNode.Items;
                        int oldEntries_count = childNode.ItemCount;
                        childNode.Items     = leftSibling.Items;
                        childNode.ItemCount = leftSibling.ItemCount;
                        for (int i = 0; i < oldEntries_count; i++)
                        {
                            childNode.Items[childNode.ItemCount - 1] = oldEntries[i];
                            childNode.ItemCount++;
                        }

                        if (!(leftSibling.ChildCount == 0))
                        {
                            Node[] oldChildren      = childNode.Children;
                            int    oldCildren_count = childNode.ChildCount;
                            childNode.Children   = leftSibling.Children;
                            childNode.ChildCount = leftSibling.ChildCount;
                            for (int i = 0; i < oldCildren_count; i++)
                            {
                                childNode.Children[childNode.ItemCount - 1] = oldChildren[i];
                                childNode.ChildCount++;
                            }
                        }

                        for (int i = leftIndex; i < parentNode.ChildCount; i++)
                        {
                            parentNode.Children[i] = parentNode.Children[i + 1];
                        }
                        parentNode.ChildCount--;

                        for (int i = subtreeIndexInNode; i < parentNode.ItemCount - 1; i++)
                        {
                            parentNode.Items[i] = parentNode.Items[i + 1];
                        }
                        parentNode.ItemCount--;
                    }
                    else
                    {
                        childNode.Items[childNode.ItemCount] = parentNode.Items[subtreeIndexInNode];
                        childNode.ItemCount++;

                        for (int i = 0; i < rightSibling.ItemCount; i++)
                        {
                            childNode.Items[childNode.ItemCount] = rightSibling.Items[i];
                            childNode.ItemCount++;
                        }

                        if (!(rightSibling.ChildCount == 0))
                        {
                            for (int i = 0; i < rightSibling.ChildCount; i++)
                            {
                                childNode.Children[childNode.ChildCount] = rightSibling.Children[i];
                                childNode.ChildCount++;
                            }
                        }

                        for (int i = rightIndex; i < parentNode.ChildCount; i++)
                        {
                            parentNode.Children[i] = parentNode.Children[i + 1];
                        }
                        parentNode.ChildCount--;

                        for (int i = subtreeIndexInNode; i < parentNode.ItemCount; i++)
                        {
                            parentNode.Items[i] = parentNode.Items[i + 1];
                        }
                        parentNode.ItemCount--;
                    }
                }
            }

            this.Remove(childNode, compare);
        }