Exemplo n.º 1
0
        private int _indexOf(AvlTreeNode <T> node)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            // the index of a node is actually that number of nodes that are "before" it. That includes
            // left children, and left siblings, including ancestors that the node is "right child" of.


            var count = _leftSize(node);
            var cur   = node;

            while (cur.Parent != null)
            {
                if (cur.Parent.Right == cur)                   // if cur is the right child of the parent
                {
                    count = count + _leftSize(cur.Parent) + 1; // count all the left descendants of the parent, and the parent itself
                }
                cur = cur.Parent;
            }

            return(count);
        }
Exemplo n.º 2
0
        private void _attachToParentEdge(AvlTreeNode <T> node, AvlTreeEdge <T> edge)
        {
            Debug.Assert(edge.IsChildOrRoot);

            // if node != null, node.parent should be free
            Debug.Assert((node == null) || (node.Parent == null));

            // if edge is child then the target should be free;
            Debug.Assert((edge.IsRoot) || (edge.Target() == null));

            if (edge.IsRoot)
            {
                _setAsRoot(node);
            }
            else if (edge.Direction == AvlTreeNodeDirection.Left)
            {
                edge.Source.Left = node;
                if (node != null)
                {
                    node.Parent = edge.Source;
                }
            }
            else
            {
                edge.Source.Right = node;
                if (node != null)
                {
                    node.Parent = edge.Source;
                }
            }
        }
Exemplo n.º 3
0
        public static AvlTreeEdge <T> FindFree <T>(this AvlTreeNode <T> source, Func <AvlTreeNode <T>, AvlTreeEdge <T> > selector)
        {
            if (source == null)
            {
                return(AvlTreeEdge <T> .Root);
            }

            var current = source;

            AvlTreeEdge <T> res = null;

            while (res == null)
            {
                var edge = selector(current);
                var next = edge.Target();

                if (next == null)
                {
                    res = edge;
                }

                current = next;
            }

            return(res);
        }
Exemplo n.º 4
0
        private AvlTreeNode <T> _doBalance(AvlTreeNode <T> node)
        {
            int bal = node.Balance;

            Debug.Assert(Math.Abs(bal) <= 2);
            AvlTreeNode <T> res = node;

            if (bal == -2)
            {
                Debug.Assert(Math.Abs(node.Left.Balance) <= 1);
                if (node.Left.Balance == 1)
                {
                    _rotateLeft(node.Left);
                }
                res = _rotateRight(node);
            }
            else if (bal == 2)
            {
                Debug.Assert(Math.Abs(node.Right.Balance) <= 1);
                if (node.Right.Balance == -1)
                {
                    node.Right = _rotateRight(node.Right);
                }
                res = _rotateLeft(node);
            }

            return(res);
        }
Exemplo n.º 5
0
        /*     Parent     Parent
         *     |-         |+
         *     B          A
         *   -/ \        / \+
         *   A   BL  -> AL   B
         *  / \-          +/ \
         * AL   C          C   BR
         *
         *   - marks connections that are dettached
         *   + marks connections that are created
         */

        private AvlTreeNode <T> _rotateRight(AvlTreeNode <T> b)
        {
            AvlTreeNode <T> a      = b.Left;
            AvlTreeNode <T> parent = b.Parent; // may be null if B was root
            AvlTreeNode <T> c      = a.Right;  // may be null

            var direction = b.Direction;

            Debug.Assert(a != null);

            // a.Left remains so no need to change this
            // b.Right remains so no need to change this

            _dettachFromParent(b); // b from parent
            _dettachFromParent(a); // a from b
            _dettachFromParent(c); // c from a

            _attachToParentEdge(c, b.EdgeLeft());
            _attachToParentEdge(b, a.EdgeRight());
            _attachToParentEdge(a, parent.EdgeTo(direction));

            _recalc(b);
            _recalc(a);
            return(a);
        }
Exemplo n.º 6
0
        internal AvlTreeNode <T> InternalPredecessor(AvlTreeNode <T> node)
        {
            Debug.Assert(node != null);

            // 3 cases:
            // case 1 - there is a left subtree, in that case, the predecessor is the last in the left sub tree.
            // case 2 - there is no left subtree, but there is a parent - the predecessor is the first parent "on the left" - so it's child is a right child
            // case 3 - no parent, or we keep clibing up parents where we are the "child on the left" - there is no predecessor

            // case 1
            if (node.Left != null)
            {
                return(InternalLastInSubtree(node.Left));
            }

            var cur = node;

            while (cur.Parent != null)
            {
                // case 2
                // if we are the right child, so the parent is on our left - this is the predecessor
                if (cur.Direction == AvlTreeNodeDirection.Right)
                {
                    return(cur.Parent);
                }

                // else - keep climbing up
                cur = cur.Parent;
            }

            // case 3 - no more parents - no predecessor
            return(null);
        }
Exemplo n.º 7
0
        private AvlTreeNode <T> rec_createRangeSubtree(T[] items, int start, int end)
        {
            if (start > end)
            {
                return(null);
            }

            var mid  = (start + end) / 2;
            var item = items[mid];

            var node  = new AvlTreeNode <T>(item);
            var left  = rec_createRangeSubtree(items, start, mid - 1);
            var right = rec_createRangeSubtree(items, mid + 1, end);

            if (left != null)
            {
                _attachToParentEdge(left, node.EdgeLeft());
            }
            if (right != null)
            {
                _attachToParentEdge(right, node.EdgeRight());
            }
            _recalc(node);
            return(node);
        }
Exemplo n.º 8
0
        public static string ToVisualString <T>(this AvlTreeNode <T> source, string textFormat = "{0}", int spacing = 2, int topMargin = 1, int leftMargin = 1)
        {
            var console = new StringConsole();

            source.PrintToConsole(console, textFormat, spacing, topMargin, leftMargin);
            return(console.ToString());
        }
Exemplo n.º 9
0
 public AvlTreeNode <T> PredecessorOf(AvlTreeNode <T> node)
 {
     if (node == null)
     {
         throw new ArgumentNullException(nameof(node));
     }
     return(InternalPredecessor(node));
 }
Exemplo n.º 10
0
 public AvlTreeNode <T> LastInSubtree(AvlTreeNode <T> node)
 {
     if (node == null)
     {
         throw new ArgumentNullException(nameof(node));
     }
     return(InternalLastInSubtree(node));
 }
Exemplo n.º 11
0
 public static AvlTreeEdge <T> For(AvlTreeNode <T> source, AvlTreeNodeDirection direction)
 {
     if (source == null)
     {
         return(Root);
     }
     return(new AvlTreeEdge <T>(source, direction));
 }
Exemplo n.º 12
0
        // Needs to be called every time the left or right subtree is changed.
        // Assumes the left and right subtrees have the correct values computed already.
        private void _recalc(AvlTreeNode <T> node)
        {
            Debug.Assert(node != null);

            node.Height = Math.Max(node.Left?.Height ?? 0, node.Right?.Height ?? 0) + 1;
            node.Size   = (node.Left?.Size ?? 0) + (node.Right?.Size ?? 0) + 1;

            Debug.Assert((node.Height >= 1) && (node.Size >= 1));
        }
Exemplo n.º 13
0
        private AvlTreeNode <T> _add(AvlTreeNode <T> node)
        {
            var item = node.Item;
            var edge = this.FindFree(n => _comparer.Compare(item, n.Item) > 0
                ? n.EdgeRight()
                : n.EdgeLeft());

            return(InternalInsertNode(edge, node));
        }
Exemplo n.º 14
0
        public AvlTreeNode <T> AddBefore(AvlTreeNode <T> anchor, T item)
        {
            if (anchor == null)
            {
                throw new ArgumentNullException(nameof(anchor));
            }
            var indexOfAnchor = anchor.LeftSize; // index of anchor relative to it's own subtree == the number of items at its left

            return(_insertInRelativeIndex(anchor, indexOfAnchor, item));
        }
Exemplo n.º 15
0
        internal AvlTreeNode <T> InternalLastInSubtree(AvlTreeNode <T> node)
        {
            Debug.Assert(node != null);

            var cur = node;

            while (cur.Right != null)
            {
                cur = cur.Right;
            }
            return(cur);
        }
Exemplo n.º 16
0
        private void _unsetRoot(AvlTreeNode <T> node)
        {
            Debug.Assert(Root == node);
            Debug.Assert((node == null) || (node.Parent == null));
            Debug.Assert((node == null) || (node._tree == this));

            Root = null;
            if (node != null)
            {
                node._tree = null;
            }
        }
Exemplo n.º 17
0
        private void _setAsRoot(AvlTreeNode <T> node)
        {
            Debug.Assert(Root == null);
            Debug.Assert(node.Parent == null);
            Debug.Assert(node._tree == null);

            Root = node;
            if (node != null)
            {
                node._tree = this;
            }
        }
Exemplo n.º 18
0
        private void _rebalanceAfterChange(AvlTreeNode <T> start)
        {
            while (start != null)
            {
                var direction = start.Direction;

                _recalc(start);
                var parent   = start.Parent;
                var balanced = _doBalance(start);

                start = parent;
            }
        }
Exemplo n.º 19
0
        private void rec_checkStructure(AvlTreeNode <T> node, ISet <AvlTreeNode <T> > visitedNodes)
        {
            if (node == null)
            {
                return;
            }

            if (!visitedNodes.Add(node))
            {
                throw new SystemException("AVL tree structure violated: Not a tree");
            }

            CheckStructureOfNode(node);

            rec_checkStructure(node.Left, visitedNodes);
            rec_checkStructure(node.Right, visitedNodes);

            if ((node.Left != null) && (node.Left.Parent != node))
            {
                throw new SystemException("AVL tree structure violated: node.Left.Parent != node");
            }

            if ((node.Right != null) && (node.Right.Parent != node))
            {
                throw new SystemException("AVL tree structure violated: node.Right.Parent != node");
            }

            if (node.Height != Math.Max((node.Left?.Height ?? 0), (node.Right?.Height ?? 0)) + 1)
            {
                throw new SystemException("AVL tree structure violated: Incorrect cached height");
            }

            if (node.Size != (node.Left?.Size ?? 0) + (node.Right?.Size ?? 0) + 1)
            {
                throw new SystemException("AVL tree structure violated: Incorrect cached size");
            }

            if (Math.Abs(node.Balance) > 1)
            {
                throw new SystemException("AVL tree structure violated: Height imbalance");
            }
        }
Exemplo n.º 20
0
        protected override void CheckStructureOfNode(AvlTreeNode <T> node)
        {
            if (node.Left != null)
            {
                var comp = _comparer.Compare(node.Item, node.Left.Item);
                if (comp < 0)
                {
                    throw new SystemException("Sorted tree, node item smaller than its left child item");
                }
            }

            if (node.Right != null)
            {
                var comp = _comparer.Compare(node.Item, node.Right.Item);
                if (comp > 0)
                {
                    throw new SystemException("Sorted tree, node item larger than its right child item");
                }
            }
        }
Exemplo n.º 21
0
        private IEnumerable <AvlTreeNode <T> > _enumerate(AvlTreeNode <T> node)
        {
            var res = Enumerable.Empty <AvlTreeNode <T> >();

            if (node == null)
            {
                return(res);
            }

            if (node.Left != null)
            {
                res = res.Concat(_enumerate(node.Left));
            }
            res = res.Concat(node);
            if (node.Right != null)
            {
                res = res.Concat(_enumerate(node.Right));
            }

            return(res);
        }
Exemplo n.º 22
0
        private AvlTreeNode <T> _insertInRelativeIndex(AvlTreeNode <T> anchor, int index, T item)
        {
            Debug.Assert(index >= 0);
            Debug.Assert((anchor != null) || (index == 0));           // if anchor is null, index must be 0
            Debug.Assert((anchor == null) || (index <= anchor.Size)); // if anchor is not null, index must be less than or queal to
                                                                      // the size of the subtree

            var newNode = new AvlTreeNode <T>(item);

            if (anchor == null)
            {
                return(InternalInsertNode(AvlTreeEdge <T> .Root, newNode));
            }

            var edge = anchor.FindFree(index, (node, idx) =>
            {
                int leftSize = node.LeftSize;
                if (idx <= leftSize)
                {
                    return(node.EdgeLeft(), idx);
                }
Exemplo n.º 23
0
        private AvlTreeNode <T> rec_getNodeAt(AvlTreeNode <T> node, int index)
        {
            var nodeSize = _size(node);

            if ((index < 0) || (index >= nodeSize))
            {
                throw new ArgumentOutOfRangeException(nameof(index));
            }

            int leftSize = _leftSize(node);

            if (index < leftSize)
            {
                return(rec_getNodeAt(node.Left, index));
            }
            if (index > leftSize)
            {
                return(rec_getNodeAt(node.Right, index - leftSize - 1));
            }

            return(node);
        }
Exemplo n.º 24
0
        internal AvlTreeNode <T> InternalInsertNode(AvlTreeEdge <T> edge, AvlTreeNode <T> newNode)
        {
            Debug.Assert(edge.IsChildOrRoot);

            if (Count == int.MaxValue)
            {
                throw new InvalidOperationException("Maximum size reached");
            }

            _version++;
            // newnode should be dettached from the tree
            Debug.Assert(newNode != null);
            Debug.Assert(newNode.Parent == null);
            Debug.Assert(newNode.Left == null);
            Debug.Assert(newNode.Right == null);
            Debug.Assert(newNode._tree == null);

            _attachToParentEdge(newNode, edge);

            _rebalanceAfterChange(edge.Source);
            return(newNode);
        }
Exemplo n.º 25
0
        private void _dettachFromParent(AvlTreeNode <T> node)
        {
            if (node == null)
            {
                return;
            }

            if (node.Parent == null)
            {
                _unsetRoot(node);
            }
            else if (node.Parent.Left == node)
            {
                node.Parent.Left = null;
                node.Parent      = null;
            }
            else
            {
                node.Parent.Right = null;
                node.Parent       = null;
            }
        }
Exemplo n.º 26
0
 internal override void OnItemChanged(AvlTreeNode <T> node)
 {
     // remove and reinsert the item so it ends up in the right place
     InternalRemoveNode(node);
     _add(node);
 }
Exemplo n.º 27
0
 private AvlTreeEdge(AvlTreeNode <T> source, AvlTreeNodeDirection direction)
 {
     Source    = source;
     Direction = direction;
 }
Exemplo n.º 28
0
 public static AvlTreeEdge <T> EdgeSelf <T>(this AvlTreeNode <T> source)
 {
     return(source.EdgeTo(AvlTreeNodeDirection.None));
 }
Exemplo n.º 29
0
 public static AvlTreeEdge <T> EdgeParent <T>(this AvlTreeNode <T> source)
 {
     return(source.EdgeTo(AvlTreeNodeDirection.Parent));
 }
Exemplo n.º 30
0
 public static AvlTreeEdge <T> EdgeTo <T>(this AvlTreeNode <T> source, AvlTreeNodeDirection direction)
 {
     return(For(source, direction));
 }