Beispiel #1
0
        public virtual TValue GetNearest <T>(T key)
        {
            IAvlLeaf <TKey, TValue> leaf = Root;
            IAvlLeaf <TKey, TValue> last = null;
            var compareKey = (TKey)Convert.ChangeType(key, typeof(TKey));

            while (leaf != null)
            {
                if (leaf.GreaterThan(compareKey))
                {
                    leaf = leaf.Left;
                }
                else if (leaf.LessThan(compareKey))
                {
                    last = leaf;
                    leaf = leaf.Right;
                }
                else
                {
                    return(leaf.Value);
                }
            }
            if (last.IsEmpty())
            {
                return(GetMaxLeaf().Value);
            }
            else
            {
                return(last.Value);
            }
        }
Beispiel #2
0
        protected virtual IAvlLeaf <TKey, TValue> BalancePostDelete(IAvlLeaf <TKey, TValue> root, bool direction,
                                                                    ref bool done)
        {
            var leaf    = root[!direction];
            var balance = direction ? 1 : -1;

            if (leaf.Balance == -balance)
            {
                root.Balance = leaf.Balance = 0;
                root         = Rotate(root, direction);
            }
            else if (leaf.Balance == balance)
            {
                DoubleRotateRebalance(root, !direction, -balance);
                root = DoubleRotate(root, direction);
            }
            else
            {
                root.Balance = -balance;
                leaf.Balance = balance;
                root         = Rotate(root, direction);
                done         = true;
            }
            return(root);
        }
Beispiel #3
0
        protected virtual IAvlLeaf <TKey, TValue> Insert(IAvlLeaf <TKey, TValue> root, IAvlLeaf <TKey, TValue> leaf,
                                                         ref bool done)
        {
            if (root.IsEmpty())
            {
                root = leaf;
            }
            else
            {
                leaf.Parent = root;
                var direction = leaf.GreaterThan(root.Key);
                root[direction] = Insert(root[direction], leaf, ref done);

                if (!done)
                {
                    root.Balance += direction ? 1 : -1;
                    if (root.Balance == 0)
                    {
                        done = true;
                    }
                    else if (Math.Abs(root.Balance) > 1)
                    {
                        root = BalancePostInsert(root, direction);
                        done = true;
                    }
                }
            }
            return(root);
        }
Beispiel #4
0
 public AvlLeaf(TKey key, TValue value, IAvlLeaf <TKey, TValue> parent)
 {
     Key      = key;
     Parent   = parent;
     Value    = value;
     Comparer = new Comparer(CultureInfo.InvariantCulture);
 }
Beispiel #5
0
        protected virtual IAvlLeaf <TKey, TValue> Rotate(IAvlLeaf <TKey, TValue> leaf, bool direction)
        {
            var working = leaf[!direction];

            leaf[!direction]   = working[direction];
            working[direction] = leaf;
            return(working);
        }
Beispiel #6
0
        protected virtual IAvlLeaf <TKey, TValue> BalancePostInsert(IAvlLeaf <TKey, TValue> root, bool direction)
        {
            var leaf    = root[direction];
            var balance = direction ? 1 : -1;

            if (leaf.Balance == balance)
            {
                root.Balance = leaf.Balance = 0;
                root         = Rotate(root, !direction);
            }
            else
            {
                DoubleRotateRebalance(root, direction, balance);
                root = DoubleRotate(root, !direction);
            }
            return(root);
        }
Beispiel #7
0
        protected virtual IAvlLeaf <TKey, TValue> Remove(IAvlLeaf <TKey, TValue> root, TKey key, ref bool done)
        {
            if (!root.IsEmpty())
            {
                bool direction = false;

                if (root.Key.Equals(key))
                {
                    if (root.Left.IsEmpty() || root.Right.IsEmpty())
                    {
                        direction = root.Left.IsEmpty();
                        var worker = root[direction];
                        return(worker);
                    }
                    else
                    {
                        var worker = root.Left;
                        while (!worker.Right.IsEmpty())
                        {
                            worker = worker.Right;
                        }

                        root.Key = worker.Key;
                        key      = worker.Key;
                    }
                }

                direction       = root.LessThan(key);
                root[direction] = Remove(root[direction], key, ref done);

                if (!done)
                {
                    root.Balance += direction ? -1 : 1;

                    if (Math.Abs(root.Balance) == 1)
                    {
                        done = true;
                    }
                    else if (Math.Abs(root.Balance) > 1)
                    {
                        root = BalancePostDelete(root, direction, ref done);
                    }
                }
            }
            return(root);
        }
Beispiel #8
0
        protected virtual void DoubleRotateRebalance(IAvlLeaf <TKey, TValue> root, bool direction, int balance)
        {
            var leaf1 = root[direction];
            var leaf2 = leaf1[!direction];

            if (leaf2.Balance == 0)
            {
                root.Balance = leaf1.Balance = 0;
            }
            else if (leaf2.Balance == balance)
            {
                root.Balance  = -balance;
                leaf1.Balance = 0;
            }
            else
            {
                root.Balance  = 0;
                leaf1.Balance = balance;
            }
            leaf2.Balance = 0;
        }
Beispiel #9
0
 protected virtual IAvlLeaf <TKey, TValue> DoubleRotate(IAvlLeaf <TKey, TValue> leaf, bool direction)
 {
     leaf[!direction] = Rotate(leaf[!direction], !direction);
     return(Rotate(leaf, direction));
 }
Beispiel #10
0
 public static bool IsEmpty <TKey, TValue>(this IAvlLeaf <TKey, TValue> leaf)
 {
     return(leaf == null || leaf.Value.Equals(default(TValue)));
 }