Esempio n. 1
0
        private AVLTreeLeaf DoubleRightTurn(AVLTreeLeaf leaf)
        {
            if (leaf == null)
            {
                throw new ArgumentNullException("leaf");
            }
            var newtop = leaf.RightLeaf.LeftLeaf;
            var beta   = newtop.LeftLeaf;
            var gamma  = newtop.RightLeaf;

            newtop.LeftLeaf           = leaf;
            newtop.RightLeaf          = leaf.RightLeaf;
            newtop.LeftLeaf.RightLeaf = beta;
            newtop.RightLeaf.LeftLeaf = gamma;
            newtop.LeftLeaf.Label     = newtop.Label == AVLLabel.R ? AVLLabel.L : AVLLabel.E;
            newtop.RightLeaf.Label    = newtop.Label == AVLLabel.L ? AVLLabel.R : AVLLabel.E;
            newtop.Label = AVLLabel.E;
            return(newtop);
        }
Esempio n. 2
0
        private AVLTreeLeaf SimpleRightTurn(AVLTreeLeaf leaf)
        {
            if (leaf == null)
            {
                throw new ArgumentNullException("leaf");
            }
            var newtop = leaf.LeftLeaf;

            leaf.LeftLeaf    = newtop.RightLeaf;
            newtop.RightLeaf = leaf;
            if (newtop.Label == AVLLabel.E)
            {
                newtop.Label = AVLLabel.R;
                leaf.Label   = AVLLabel.L;
            }
            else
            {
                newtop.Label = AVLLabel.E;
                leaf.Label   = AVLLabel.E;
            }
            return(newtop);
        }
Esempio n. 3
0
 public void Clear()
 {
     this._root  = null;
     this._count = 0;
 }
Esempio n. 4
0
        public bool AddDistinct(T item)
        {
            if (this._count == 0)
            {
                this._root = new AVLTreeLeaf {
                    Value = item, Label = AVLLabel.E
                };
            }
            else
            {
                var current = this._root;
                var trace   = new Stack <Tuple <AVLTreeLeaf, Direction> >();
                while (true)
                {
                    var d = this._comparer.Compare(current.Value, item);
                    if (d == 0) // this item is already inserted.
                    {
                        return(false);
                    }
                    if (d > 0)
                    {
                        trace.Push(Tuple.Create(current, Direction.Left));
                        if (current.LeftLeaf != null)
                        {
                            current = current.LeftLeaf;
                        }
                        else
                        {
                            current.LeftLeaf = new AVLTreeLeaf {
                                Value = item, Label = AVLLabel.E
                            };
                            break;
                        }
                    }
                    else
                    {
                        trace.Push(Tuple.Create(current, Direction.Right));
                        if (current.RightLeaf != null)
                        {
                            current = current.RightLeaf;
                        }
                        else
                        {
                            current.RightLeaf = new AVLTreeLeaf {
                                Value = item, Label = AVLLabel.E
                            };
                            break;
                        }
                    }
                }

                // rotate and balance
                while (trace.Count > 0)
                {
                    var tuple = trace.Pop();
                    var node  = tuple.Item1;
                    if (tuple.Item2 == Direction.Right)
                    {
                        // come from right
                        if (tuple.Item1.Label == AVLLabel.E) // CONTINUE
                        {
                            tuple.Item1.Label = AVLLabel.R;
                            continue;
                        }
                        if (tuple.Item1.Label == AVLLabel.R)
                        {
                            node = node.RightLeaf.Label == AVLLabel.L ?
                                   this.DoubleRightTurn(node) : this.SimpleLeftTurn(node);
                        }
                        else
                        {
                            tuple.Item1.Label = AVLLabel.E;
                        }
                    }
                    else
                    {
                        // come from left
                        if (tuple.Item1.Label == AVLLabel.E) // CONTINUE
                        {
                            tuple.Item1.Label = AVLLabel.L;
                            continue;
                        }
                        if (tuple.Item1.Label == AVLLabel.L)
                        {
                            node = node.LeftLeaf.Label == AVLLabel.R ?
                                   this.DoubleLeftTurn(node) : this.SimpleRightTurn(node);
                        }
                        else
                        {
                            tuple.Item1.Label = AVLLabel.E;
                        }
                    }

                    // attach new node
                    if (trace.Count > 0)
                    {
                        var peek = trace.Peek();
                        if (peek.Item2 == Direction.Left)
                        {
                            peek.Item1.LeftLeaf = node;
                        }
                        else
                        {
                            peek.Item1.RightLeaf = node;
                        }
                    }
                    else
                    {
                        this._root = node;
                    }
                    break; // END
                }
            }
            this._count++;
            return(true);
        }
Esempio n. 5
0
        public bool Remove(T item)
        {
            if (this._count == 0)
            {
                return(false);
            }
            // find node
            var current = this._root;
            var trace   = new Stack <Tuple <AVLTreeLeaf, Direction> >();

            while (true)
            {
                var d = this._comparer.Compare(current.Value, item);
                if (d == 0) // this item is already inserted.
                {
                    // found
                    break;
                }
                if (d > 0)
                {
                    trace.Push(Tuple.Create(current, Direction.Left));

                    if (current.LeftLeaf != null)
                    {
                        current = current.LeftLeaf;
                    }
                    else // not found
                    {
                        return(false);
                    }
                }
                else
                {
                    trace.Push(Tuple.Create(current, Direction.Right));

                    if (current.RightLeaf != null)
                    {
                        current = current.RightLeaf;
                    }
                    else // not found
                    {
                        return(false);
                    }
                }
            }

            // remove node
            if (current.LeftLeaf != null && current.RightLeaf != null)
            {
                // has two children
                trace.Push(Tuple.Create(current, Direction.Left));

                // get most right element in the left sub-tree
                var child = current.LeftLeaf;
                while (child.RightLeaf != null)
                {
                    trace.Push(Tuple.Create(child, Direction.Right));
                    child = child.RightLeaf;
                }
                // remove most-right children
                var peek = trace.Peek();
                if (peek.Item2 == Direction.Left)
                {
                    trace.Peek().Item1.LeftLeaf = child.LeftLeaf;
                }
                else
                {
                    trace.Peek().Item1.RightLeaf = child.LeftLeaf;
                }
                current.Value = child.Value;
            }
            else
            {
                if (trace.Count == 0)
                {
                    // top of the tree
                    this._root = current.LeftLeaf ?? current.RightLeaf;
                }
                else
                {
                    var parent = trace.Peek();
                    // has a child or no children
                    AVLTreeLeaf leaf;
                    if (current.LeftLeaf != null)
                    {
                        leaf = current.LeftLeaf;
                    }
                    else if (current.RightLeaf != null)
                    {
                        leaf = current.RightLeaf;
                    }
                    else // has no children
                    {
                        leaf = null;
                    }

                    if (parent.Item2 == Direction.Left)
                    {
                        parent.Item1.LeftLeaf = leaf;
                    }
                    else
                    {
                        parent.Item1.RightLeaf = leaf;
                    }
                }
            }

            // rotate and balance
            while (trace.Count > 0)
            {
                var breakLoop = false;
                var tuple     = trace.Pop();
                var node      = tuple.Item1;
                if (tuple.Item2 == Direction.Left)
                {
                    // come from left
                    if (tuple.Item1.Label == AVLLabel.L)
                    {
                        tuple.Item1.Label = AVLLabel.E;
                        continue;
                    }
                    if (tuple.Item1.Label == AVLLabel.R)
                    {
                        if (node.RightLeaf.Label == AVLLabel.L)
                        {
                            node = this.DoubleRightTurn(node);
                        }
                        else
                        {
                            node      = this.SimpleLeftTurn(node);
                            breakLoop = node.Label == AVLLabel.L;
                        }
                    }
                    else
                    {
                        tuple.Item1.Label = AVLLabel.R;
                        break;
                    }
                }
                else
                {
                    // come from right
                    if (tuple.Item1.Label == AVLLabel.R)
                    {
                        tuple.Item1.Label = AVLLabel.E;
                        continue;
                    }
                    if (tuple.Item1.Label == AVLLabel.L)
                    {
                        if (node.LeftLeaf.Label == AVLLabel.R)
                        {
                            node = this.DoubleLeftTurn(node);
                        }
                        else
                        {
                            node      = this.SimpleRightTurn(node);
                            breakLoop = node.Label != AVLLabel.E;
                        }
                    }
                    else
                    {
                        tuple.Item1.Label = AVLLabel.L;
                        break;
                    }
                }

                // attach new node
                if (trace.Count > 0)
                {
                    var peek = trace.Peek();
                    if (peek.Item2 == Direction.Left)
                    {
                        peek.Item1.LeftLeaf = node;
                    }
                    else
                    {
                        peek.Item1.RightLeaf = node;
                    }
                }
                else
                {
                    this._root = node;
                }
                if (breakLoop)
                {
                    break;
                }
            }
            this._count--;
            return(true);
        }