public static ICollection <T> Synchronized(LinkedDeque <T> list) { return(new SynchronizedCollection(list)); }
/// <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); }
internal SynchronizedCollection(LinkedDeque <T> deque) { _deque = deque; _collection = deque; _root = _collection.SyncRoot; }