// ****************************************************************** 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); }
// ****************************************************************** 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); }
// ****************************************************************** /// <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; } }
// ****************************************************************** /// <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; } }
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); } }
// ****************************************************************** // 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); }
// ****************************************************************** 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); }
// ****************************************************************** public void Reset() { _current = null; }
// ****************************************************************** // 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); } } }
// ****************************************************************** public void Clear() { _root = null; _count = 0; }