/// <summary>
        /// Слияние двух узлов.
        /// </summary>
        /// <param name="sibling">Брат, с которым происходит слияние.</param>
        public override void Merge(LinkedNode <T> sibling)
        {
            InternalLinkedNode <T> node = (InternalLinkedNode <T>)sibling;

            //Спускает Separator сверху
            Keys.Add(node.GetFirstLeafKey());
            Keys.AddRange(node.Keys);
            Children.AddRange(node.Children);
        }
        /// <summary>
        /// Рекурсивное добавление ключа в узел. Внутренние узлы
        /// передают управление листьевым, где и производится
        /// добавление. Возможна перестройка структуры дерева из-за
        /// переполнения ключей.
        /// </summary>
        /// <param name="key">Добавляемый ключ.</param>
        public override void Add(T key)
        {
            LinkedNode <T> child = GetChild(key);

            child.Add(key);
            if (child.IsOverflow())
            {
                LinkedNode <T> sibling = child.Split();
                InsertChild(sibling.GetFirstLeafKey(), sibling);
            }
        }
        /// <summary>
        /// Добавление ключа и связанного с ним потомка.
        /// </summary>
        /// <param name="key">Ключ.</param>
        /// <param name="child">Потомок.</param>
        private void InsertChild(T key, LinkedNode <T> child)
        {
            int location   = Keys.IndexInSorted(key);
            int childIndex = location >= 0 ? location + 1 : -location - 1;

            if (location >= 0)
            {
                Children[childIndex] = child;
            }
            else
            {
                Keys.Insert(childIndex, key);
                Children.Insert(childIndex + 1, child);
            }
        }
예제 #4
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;
            }
        }
예제 #5
0
        /// <summary>
        /// Добавление элемента в дерево
        /// </summary>
        /// <param name="node">Элемент</param>
        public void Add(T node)
        {
            if (_root == null)
            {
                Level++;
                _root = new LeafLinkedNode <T>(Factor);
            }

            _root.Add(node);

            if (_root.IsOverflow())
            {
                Level++;
                var sibling = _root.Split();
                var newRoot = new InternalLinkedNode <T>(Factor);
                newRoot.Keys.Add(sibling.GetFirstLeafKey());
                newRoot.Children.Add(_root);
                newRoot.Children.Add(sibling);
                _root = newRoot;
            }
        }
        /// <summary>
        /// Рекурсивное удаление ключа из узла. Внутренние узлы
        /// передают управление листьевым, откуда и производится
        /// удаление. Возможна перестройка структуры дерева из-за
        /// нехватки ключей.
        /// </summary>
        /// <param name="key">Удаляемый ключ</param>
        /// <returns>
        /// Узел дерева, который станет новым корнем, если в текущем корне
        /// не останется ключей.
        /// </returns>
        public override LinkedNode <T> Remove(T key)
        {
            //Выбор потомка, которому нужно передать удаление
            LinkedNode <T> child = GetChild(key);

            child.Remove(key);
            if (child.IsUnderFlow())
            {
                LinkedNode <T> childLeftSibling  = GetChildLeftSibling(key);
                LinkedNode <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
                    {
                        LinkedNode <T> left  = childLeftSibling ?? child;
                        LinkedNode <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())
                        {
                            LinkedNode <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);
        }
예제 #7
0
 public abstract void Merge(LinkedNode <T> sibling);
예제 #8
0
 /// <summary>
 /// Очистка дерева
 /// </summary>
 public void Clear()
 {
     _root = null;
     Level = 0;
 }