public virtual TValue GetNearest <T>(T key) { IRedBlackLeaf <TKey, TValue> leaf = Root; IRedBlackLeaf <TKey, TValue> last = null; var compareKey = (TKey)Convert.ChangeType(key, typeof(TKey)); var compare = CreateLeaf(compareKey, default(TValue)); while (leaf != null) { if (leaf.GreaterThan(compare)) { leaf = leaf.Left; } else if (leaf.LessThan(compare)) { last = leaf; leaf = leaf.Right; } else { return(leaf.Value); } } if (last.IsEmpty()) { return(GetMaxLeaf().Value); } else { return(last.Value); } }
public virtual IRedBlackLeaf <TKey, TValue> Remove(IRedBlackLeaf <TKey, TValue> root, TKey key, ref bool done) { if (root.IsEmpty()) { done = true; } else { bool direction; if (root.Key.Equals(key)) { if (root.Left.IsEmpty() || root.Right.IsEmpty()) { var save = root[root.Left.IsEmpty()]; if (root.IsRed()) { done = true; } else if (save.IsRed()) { save.Color = LeafColor.BLACK; done = true; } return(save); } else { var heir = root.Left; while (!heir.Right.IsEmpty()) { heir = heir.Right; } root.Value = heir.Value; root.Key = heir.Key; key = heir.Key; } } direction = root.LessThan(CreateLeaf(key, default(TValue))); root[direction] = Remove(root[direction], key, ref done); if (!done) { root = BalancePostDelete(root, direction, ref done); } } return(root); }
public virtual IRedBlackLeaf <TKey, TValue> Insert(IRedBlackLeaf <TKey, TValue> root, IRedBlackLeaf <TKey, TValue> leaf) { if (root.IsEmpty()) { root = leaf; } else { leaf.Parent = root; var direction = leaf.GreaterThan(root); root[direction] = Insert(root[direction], leaf); root = BalancePostInsert(root, direction); } return(root); }
public virtual TValue Get(TKey key) { Lock.EnterReadLock(); IRedBlackLeaf <TKey, TValue> leaf = Root; var compare = CreateLeaf(key, default(TValue)); while (leaf != null) { if (leaf.GreaterThan(compare)) { leaf = leaf.Left; } else if (leaf.LessThan(compare)) { leaf = leaf.Right; } else { break; } } Lock.ExitReadLock(); return(leaf.IsEmpty() ? default(TValue) : leaf.Value); }
public virtual IRedBlackLeaf <TKey, TValue> BalancePostDelete(IRedBlackLeaf <TKey, TValue> root, bool direction, ref bool done) { IRedBlackLeaf <TKey, TValue> worker = root; IRedBlackLeaf <TKey, TValue> leaf = root[!direction]; if (leaf.IsRed()) { root = Rotate(root, direction); leaf = worker[!direction]; } if (!leaf.IsEmpty()) { if (leaf.Left.IsBlack() && leaf.Right.IsBlack()) { if (worker.IsRed()) { done = true; } worker.Color = LeafColor.BLACK; leaf.Color = LeafColor.RED; } else { var save = worker.IsRed(); var newRoot = root.Key.Equals(worker.Key); if (leaf[!direction].IsRed()) { worker = Rotate(worker, direction); } else { worker = DoubleRotate(worker, direction); } worker.Color = save ? LeafColor.RED : LeafColor.BLACK; if (!worker.Left.IsEmpty()) { worker.Left.Color = LeafColor.BLACK; } if (!worker.Right.IsEmpty()) { worker.Right.Color = LeafColor.BLACK; } if (newRoot) { root = worker; } else { root[direction] = worker; } done = true; } } return(root); }
public static bool IsBlack <TKey, TValue>(this IRedBlackLeaf <TKey, TValue> leaf) { return(!leaf.IsEmpty() && leaf.Color == LeafColor.BLACK); }
public override IRedBlackLeaf <TKey, TValue> Insert(IRedBlackLeaf <TKey, TValue> root, IRedBlackLeaf <TKey, TValue> leaf) { if (Root.IsEmpty()) { Root = leaf; } else { IRedBlackLeaf <TKey, TValue> g, t, p, q, head; head = new RedBlackLeaf <TKey, TValue>(default(TKey), default(TValue), null); g = t = q = p = null; bool direction, last; direction = last = false; t = head; q = t.Right = Root; for ( ;;) { if (q.IsEmpty()) { p[direction] = q = leaf; if (q.IsEmpty()) { return(Root); } } else if (q.Left.IsRed() && q.Right.IsRed()) { q.Color = LeafColor.RED; q.Left.Color = LeafColor.BLACK; q.Right.Color = LeafColor.BLACK; } if (q.IsRed() && p.IsRed()) { var newDirection = t.Right.Key.Equals(g.Key); var lastIteration = p[last]; var lastIterationKey = lastIteration == null ? default(TKey) : lastIteration.Key; if (q.Key.Equals(lastIterationKey)) { t[newDirection] = Rotate(g, !last); } else { t[newDirection] = DoubleRotate(g, !last); } } if (q.Key.Equals(leaf.Key)) { break; } last = direction; direction = q.LessThan(leaf); if (!g.IsEmpty()) { t = g; } g = p; p = q; q = q[direction]; } Root = head.Right; } Root.Color = LeafColor.BLACK; return(Root); }