/// <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); } }
/// <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; } }
/// <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); }
public abstract void Merge(LinkedNode <T> sibling);
/// <summary> /// Очистка дерева /// </summary> public void Clear() { _root = null; Level = 0; }