Beispiel #1
0
        /// <summary>
        /// Удаление элемента из дерева
        /// </summary>
        /// <param name="node">Удаляемый элемент</param>
        public void Remove(T node)
        {
            if (_root == null)
            {
                return;
            }

            var newRoot = _root.Remove(node);

            if (_root.IsUnderFlow())
            {
                Level--;
                _root = newRoot;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Рекурсивное удаление ключа из узла. Внутренние узлы
        /// передают управление листьевым, откуда и производится
        /// удаление. Возможна перестройка структуры дерева из-за
        /// нехватки ключей.
        /// </summary>
        /// <param name="key">Удаляемый ключ</param>
        /// <returns>
        /// Узел дерева, который станет новым корнем, если в текущем корне
        /// не останется ключей.
        /// </returns>
        public override ArrayNode <T> Remove(T key)
        {
            //Выбор потомка, которому нужно передать удаление
            ArrayNode <T> child = GetChild(key);

            child.Remove(key);
            if (child.IsUnderFlow())
            {
                ArrayNode <T> childLeftSibling  = GetChildLeftSibling(key);
                ArrayNode <T> childRightSibling = GetChildRightSibling(key);
                if (childRightSibling != null && childRightSibling.Keys.Count >= Factor)
                {
                    T borrowed = childRightSibling.Keys[0];
                    child.Keys.Add(borrowed);
                    childRightSibling.Keys.Remove(borrowed);
                    T   newSeparator = childRightSibling.Keys[0];
                    int location     = Keys.IndexInSorted(newSeparator);
                    if (location < 0)
                    {
                        Keys[-location - 2] = newSeparator;
                    }
                }
                else
                {
                    if (childLeftSibling != null && childLeftSibling.Keys.Count >= Factor)
                    {
                        T borrowed = childLeftSibling.Keys[childLeftSibling.Keys.Count - 1];
                        child.Keys.Add(borrowed);
                        childLeftSibling.Keys.Remove(borrowed);
                    }
                    else
                    {
                        ArrayNode <T> left  = childLeftSibling ?? child;
                        ArrayNode <T> right = childLeftSibling != null ? child : childRightSibling;
                        left.Merge(right);
                        //right никогда не null
                        if (right.Keys.Count == 0 && Keys.Contains(key))
                        {
                            DeleteChild(key);
                        }
                        else
                        {
                            DeleteChild(right.GetFirstLeafKey());
                        }

                        if (left.IsOverflow())
                        {
                            ArrayNode <T> sibling = left.Split();
                            InsertChild(sibling.GetFirstLeafKey(), sibling);
                        }

                        return(left);
                    }
                }
            }

            int updateIndex = Keys.IndexOf(key);

            if (updateIndex >= 0)
            {
                Keys[updateIndex] = Children[updateIndex + 1].GetFirstLeafKey();
            }
            return(null);
        }