コード例 #1
0
        // ******************************************************************
        private AvlNode <T> CopyTreeRecursive(AvlNode <T> source, AvlNode <T> copyParent)
        {
            if (source == null)
            {
                return(null);
            }

            AvlNode <T> copy = new AvlNode <T>();

            copy.Parent  = copyParent;
            copy.Item    = source.Item;
            copy.Balance = source.Balance;
            copy.Left    = CopyTreeRecursive(source.Left, copy);
            copy.Right   = CopyTreeRecursive(source.Right, copy);

            return(copy);
        }
コード例 #2
0
        // ******************************************************************
        public bool MoveNext()
        {
            if (_current == null)
            {
                _current = _avlTree.GetLastNode();
            }
            else
            {
                _current = _current.GetPreviousNode();
            }

            if (_current == null)             // Should check for an empty tree too :-)
            {
                return(false);
            }

            return(true);
        }
コード例 #3
0
        // ******************************************************************
        /// <summary>
        /// EO: New
        /// </summary>
        /// <param name="itemToDelete"></param>
        /// <param name="child"></param>

        private void ReplaceSafe(AvlNode <T> itemToDelete, AvlNode <T> child)
        {
            child.Parent = itemToDelete.Parent;
            if (itemToDelete.Parent != null)
            {
                if (itemToDelete.Parent.Left == itemToDelete)
                {
                    itemToDelete.Parent.Left = child;
                }
                else if (itemToDelete.Parent.Right == itemToDelete)
                {
                    itemToDelete.Parent.Right = child;
                }
            }
            else
            {
                _root = child;
            }
        }
コード例 #4
0
        // ******************************************************************
        /// <summary>
        /// WARNING THIS METHOD is modifying the node content.
        /// This weird behavior cause side effect which could invalid any node previously referenced.
        /// This method is used to remove node.
        ///
        /// - THE BIG QUESTION is: Should I be able to obtain a ref on the node or not (like I added for remove nmode)???
        /// - My answer is "NO" theoritically but in real life I say "YES" I want a ref in order to be more efficient in my context.
        /// - I know that this could affect the Tree implementtion abstraction which could be prevented to change in the future
        /// because I play with inner stuff but honestly, for performance here, I  don't give a shit.
        ///
        /// But could I replace node without touching the item? I should be able. It cost a little more thought :-)
        /// </summary>
        /// <param name="target"></param>
        /// <param name="source"></param>

        private static void Replace(AvlNode <T> target, AvlNode <T> source)
        {
            AvlNode <T> left  = source.Left;
            AvlNode <T> right = source.Right;

            target.Balance = source.Balance;
            target.Item    = source.Item;
            target.Left    = left;
            target.Right   = right;

            if (left != null)
            {
                left.Parent = target;
            }

            if (right != null)
            {
                right.Parent = target;
            }
        }
コード例 #5
0
        private void RecursiveEnsureNodeBalanceIsValid(AvlNode <T> node)
        {
            int leftHeight  = GetMaxHeightRecursive(node.Left);
            int rightHeight = GetMaxHeightRecursive(node.Right);

            if (leftHeight == 0)
            {
                if (rightHeight == 0)
                {
                    DumpIfNotTrue(node.Balance == 0);
                }
                else
                {
                    DumpIfNotTrue(node.Balance == -1);
                }
            }
            else
            {
                if (rightHeight == 0)
                {
                    DumpIfNotTrue(node.Balance == 1);
                }
                else
                {
                    DumpIfNotTrue(node.Balance == leftHeight - rightHeight);
                }
            }

            if (node.Left != null)
            {
                RecursiveEnsureNodeBalanceIsValid(node.Left);
            }

            if (node.Right != null)
            {
                RecursiveEnsureNodeBalanceIsValid(node.Right);
            }
        }
コード例 #6
0
        // ******************************************************************
        // No side effect on any node previously referenced, other than the deleted one and/or root if deleted node is the root
        public virtual bool RemoveSafe(T item)
        {
            AvlNode <T> node = _root;

            while (node != null)
            {
                if (_comparer.Compare(item, node.Item) < 0)
                {
                    node = node.Left;
                }
                else if (_comparer.Compare(item, node.Item) > 0)
                {
                    node = node.Right;
                }
                else
                {
                    RemoveNodeSafe(node);
                    return(true);
                }
            }

            return(false);
        }
コード例 #7
0
        // ******************************************************************
        public AvlNode <T> GetNode(T item)
        {
            AvlNode <T> node = _root;

            while (node != null)
            {
                int compareResult = _comparer.Compare(item, node.Item);
                if (compareResult < 0)
                {
                    node = node.Left;
                }
                else if (compareResult > 0)
                {
                    node = node.Right;
                }
                else
                {
                    return(node);
                }
            }

            return(null);
        }
コード例 #8
0
 // ******************************************************************
 public void Reset()
 {
     _current = null;
 }
コード例 #9
0
        // ******************************************************************
        // No side effect on any node previously referenced, other than the deleted one and/or root if deleted node is the root
        public void RemoveNodeSafe(AvlNode <T> node)
        {
            _count--;

            AvlNode <T> left  = node.Left;
            AvlNode <T> right = node.Right;

            if (left == null)
            {
                if (right == null)
                {
                    if (node == _root)
                    {
                        _root = null;
                    }
                    else
                    {
                        if (node.Parent.Left == node)
                        {
                            node.Parent.Left = null;

                            RemoveBalance(node.Parent, -1);
                        }
                        else if (node.Parent.Right == node)
                        {
                            node.Parent.Right = null;

                            RemoveBalance(node.Parent, 1);
                        }
                        else
                        {
                            DumpVisual2();
                            Debug.Assert(false);                             // Duplicate values ???
                        }
                    }
                }
                else
                {
                    ReplaceSafe(node, right);
                    RemoveBalance(right, 0);
                }
            }
            else if (right == null)
            {
                ReplaceSafe(node, left);
                RemoveBalance(left, 0);
            }
            else
            {
                AvlNode <T> successor = right;

                if (successor.Left == null)
                {
                    AvlNode <T> parent = node.Parent;

                    successor.Parent  = parent;
                    successor.Left    = left;
                    successor.Balance = node.Balance;

                    left.Parent = successor;

                    if (node == _root)
                    {
                        _root = successor;
                    }
                    else
                    {
                        if (parent.Left == node)
                        {
                            parent.Left = successor;
                        }
                        else
                        {
                            parent.Right = successor;
                        }
                    }

                    RemoveBalance(successor, 1);
                }
                else
                {
                    while (successor.Left != null)
                    {
                        successor = successor.Left;
                    }

                    AvlNode <T> parent          = node.Parent;
                    AvlNode <T> successorParent = successor.Parent;
                    AvlNode <T> successorRight  = successor.Right;

                    if (successorParent.Left == successor)
                    {
                        successorParent.Left = successorRight;
                    }
                    else
                    {
                        successorParent.Right = successorRight;
                    }

                    if (successorRight != null)
                    {
                        successorRight.Parent = successorParent;
                    }

                    successor.Parent  = parent;
                    successor.Left    = left;
                    successor.Balance = node.Balance;
                    successor.Right   = right;
                    right.Parent      = successor;

                    left.Parent = successor;

                    if (node == _root)
                    {
                        _root = successor;
                    }
                    else
                    {
                        if (parent.Left == node)
                        {
                            parent.Left = successor;
                        }
                        else
                        {
                            parent.Right = successor;
                        }
                    }

                    RemoveBalance(successorParent, -1);
                }
            }
        }
コード例 #10
0
 // ******************************************************************
 public void Clear()
 {
     _root  = null;
     _count = 0;
 }