예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
 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);
 }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
 public static bool IsBlack <TKey, TValue>(this IRedBlackLeaf <TKey, TValue> leaf)
 {
     return(!leaf.IsEmpty() && leaf.Color == LeafColor.BLACK);
 }
예제 #7
0
        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);
        }