예제 #1
0
 public static ICollection <T> Synchronized(LinkedDeque <T> list)
 {
     return(new SynchronizedCollection(list));
 }
예제 #2
0
        /// <inheritdoc />
        public override bool Remove(T value)
        {
            /*
             * Udemy courses sometimes contains garbage! the previous code was wrong or contains
             * at least 2 bugs! Avoid the following implementations for BST or AVL trees:
             * Buggy: Master the Coding Interview Data Structures + Algorithms - Andrei Neagoie.
             * Less than optimal: Mastering Data Structures & Algorithms using C and C++ - Abdul Bari
             *
             * This one is much better but with a small modification because it contains a bug as well
             * for not handling leaf nodes.
             * https://www.geeksforgeeks.org/binary-search-tree-set-3-iterative-delete/?ref=rp
             */
            if (Root == null)
            {
                return(false);
            }

            LinkedBinaryNode <T> parent = null, node = null, next = Root;
            // the deque has the same effect as the recursive call but only it's iterative now
            // will need to use a deque or a linked list instead of the stack because of swap in case 3
            LinkedDeque <LinkedBinaryNode <T> > deque = new LinkedDeque <LinkedBinaryNode <T> >();

            // find the node. as a general rule: whenever a node's left or right changes, it will be pushed to get updated
            while (next != null)
            {
                int order = Comparer.Compare(value, next.Value);

                if (order == 0)
                {
                    node = next;
                    break;
                }

                parent = next;
                deque.Push(parent);
                next = order < 0
                                                        ? next.Left
                                                        : next.Right;
            }

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

            // case 1: node has no children
            if (node.IsLeaf)
            {
                if (parent == null)
                {
                    Root = null;
                }
                else
                {
                    if (ReferenceEquals(parent.Left, node))
                    {
                        parent.Left = null;
                    }
                    else
                    {
                        parent.Right = null;
                    }
                }
            }
            // case 2: node has one child
            else if (node.HasOneChild)
            {
                LinkedBinaryNode <T> newNode = node.Left ?? node.Right;

                if (parent == null)
                {
                    Root = newNode;
                }
                else
                {
                    if (ReferenceEquals(parent.Left, node))
                    {
                        parent.Left = newNode;
                    }
                    else
                    {
                        parent.Right = newNode;
                    }
                }
            }
            // case 3: node has 2 children
            else
            {
                // find the right child's left most child (successor)
                LinkedBinaryNode <T> leftMostParent = null;
                LinkedBinaryNode <T> successor      = node.Right;

                while (successor.Left != null)
                {
                    leftMostParent = successor;
                    deque.Push(leftMostParent);
                    successor = successor.Left;
                }

                /*
                 * if there is a left-most for the node's right node, then
                 * move its right to its parent's left.
                 */
                if (leftMostParent != null)
                {
                    leftMostParent.Left = successor.Right;

                    // insert the node because it will be swapped later with the successor
                    if (parent != null)
                    {
                        deque.PushBefore(parent, node);
                    }
                    else
                    {
                        deque.PushLast(node);
                    }
                }
                // Otherwise, move the successor's right to the node's right
                else
                {
                    node.Right = successor.Right;
                    deque.Push(node);
                }

                // swap the value with the successor
                node.Swap(successor);
            }

            // update parents
            while (deque.Count > 0)
            {
                node = deque.Pop();
                SetHeight(node);
                // check the balance
                if (Math.Abs(node.BalanceFactor) <= BALANCE_FACTOR)
                {
                    continue;
                }
                parent = deque.Count > 0
                                                        ? deque.PeekTail()
                                                        : null;
                bool isLeft = parent != null && ReferenceEquals(parent.Left, node);
                node = Balance(node);

                if (parent == null)
                {
                    Root = node;
                }
                else
                {
                    if (isLeft)
                    {
                        parent.Left = node;
                    }
                    else
                    {
                        parent.Right = node;
                    }

                    SetHeight(parent);
                }
            }

            Count--;
            _version++;
            return(true);
        }
예제 #3
0
 internal SynchronizedCollection(LinkedDeque <T> deque)
 {
     _deque      = deque;
     _collection = deque;
     _root       = _collection.SyncRoot;
 }