private void RightRotation() { // c (this) // / // b // / // a // // becomes // b // / \ // a c // Note: RightRotation is basically the opposite of LeftRotation AVLTreeNode <TNode> newRoot = Left; // replace the current root with the new root ReplaceRoot(newRoot); // take ownership of left's right child as left (now parent) Left = newRoot.Right; // the new root takes this as it's right newRoot.Right = this; }
public bool Remove(T value) { AVLTreeNode <T> current; current = Find(value); if (current == null) { return(false); } AVLTreeNode <T> treeToBalance = current.Parent; Count--; if (current.Right == null) { if (current.Parent == null) { Head = current.Left; if (Head != null) { Head.Parent = null; } } else { int result = current.Parent.CompareTo(current.Value); if (result > 0) { current.Parent.Left = current.Left; } else if (result < 0) { current.Parent.Right = current.Left; } } } else if (current.Right.Left == null) { current.Right.Left = current.Left; if (current.Parent == null) { Head = current.Right; if (Head != null) { Head.Parent = null; } } else { int result = current.Parent.CompareTo(current.Value); if (result > 0) { current.Parent.Left = current.Right; } else if (result < 0) { current.Parent.Right = current.Right; } } } else { AVLTreeNode <T> leftmost = current.Right.Left; while (leftmost.Left != null) { leftmost = leftmost.Left; } leftmost.Parent.Left = leftmost.Right; leftmost.Left = current.Left; leftmost.Right = current.Right; if (current.Parent == null) { Head = leftmost; if (Head != null) { Head.Parent = null; } } else { int result = current.Parent.CompareTo(current.Value); if (result > 0) { current.Parent.Left = leftmost; } else if (result < 0) { current.Parent.Right = leftmost; } } } if (treeToBalance != null) { treeToBalance.Balance(); } else { if (Head != null) { Head.Balance(); } } return(true); }
public bool Remove(T value) { AVLTreeNode <T> current; current = Find(value); // находим узел с удаляемым значением if (current == null) // узел не найден { return(false); } AVLTreeNode <T> treeToBalance = current.Parent; // баланс дерева относительно узла родителя Count--; // уменьшение колиества узлов // Вариант 1: Если удаляемый узел не имеет правого потомка if (current.Right == null) // если нет правого потомка { if (current.Parent == null) // удаляемый узел является корнем { Head = current.Left; // на место корня перемещаем левого потомка if (Head != null) { Head.Parent = null; // убераем ссылку на родителя } } else // удаляемый узел не является корнем { int result = current.Parent.CompareTo(current.Value); if (result > 0) { // Если значение родительского узла больше значения удаляемого, // сделать левого потомка удаляемого узла, левым потомком родителя. current.Parent.Left = current.Left; } else if (result < 0) { // Если значение родительского узла меньше чем удаляемого, // сделать левого потомка удаляемого узла - правым потомком родительского узла. current.Parent.Right = current.Left; } } } // Вариант 2: Если правый потомок удаляемого узла не имеет левого потомка, тогда правый потомок удаляемого узла // становится потомком родительского узла. else if (current.Right.Left == null) // если у правого потомка нет левого потомка { current.Right.Left = current.Left; if (current.Parent == null) // текущий элемент является корнем { Head = current.Right; if (Head != null) { Head.Parent = null; } } else { int result = current.Parent.CompareTo(current.Value); if (result > 0) { // Если значение узла родителя больше чем значение удаляемого узла, // сделать правого потомка удаляемого узла, левым потомком его родителя. current.Parent.Left = current.Right; } else if (result < 0) { // Если значение родительского узла меньше значения удаляемого, // сделать правого потомка удаляемого узла - правым потомком родителя. current.Parent.Right = current.Right; } } } // Вариант 3: Если правый потомок удаляемого узла имеет левого потомка, // заместить удаляемый узел, крайним левым потомком правого потомка. else { // Нахожление крайнего левого узла для правого потомка удаляемого узла. AVLTreeNode <T> leftmost = current.Right.Left; while (leftmost.Left != null) { leftmost = leftmost.Left; } // Родительское правое поддерево становится родительским левым поддеревом. leftmost.Parent.Left = leftmost.Right; // Присвоить крайнему левому узлу, ссылки на правого и левого потомка удаляемого узла. leftmost.Left = current.Left; leftmost.Right = current.Right; if (current.Parent == null) { Head = leftmost; if (Head != null) { Head.Parent = null; } } else { int result = current.Parent.CompareTo(current.Value); if (result > 0) { // Если значение родительского узла больше значения удаляемого, // сделать крайнего левого потомка левым потомком родителя удаляемого узла. current.Parent.Left = leftmost; } else if (result < 0) { // Если значение родительского узла, меньше чем значение удаляемого, // сделать крайнего левого потомка, правым потомком родителя удаляемого узла. current.Parent.Right = leftmost; } } } if (treeToBalance != null) { treeToBalance.Balance(); } else { if (Head != null) { Head.Balance(); } } return(true); }
/// <summary> /// Removes all items from the tree /// </summary> public void Clear() { _head = null; _count = 0; }
/// <summary> /// Removes the first occurance of the specified value from the tree. /// </summary> /// <param name="value">The value to remove</param> /// <returns>True if the value was removed, false otherwise</returns> public bool Remove(T value) { AVLTreeNode <T> current; // Find the node to remove current = Find(value); // If no such node, then just return false if (current == null) { return(false); } AVLTreeNode <T> treeToBalance = current.Parent; _count--; // Case 1: If current has no right child, then // current's left replaces current if (current.Right == null) { // The node to be removed is the head node if (current.Parent == null) { _head = current.Left; if (_head != null) { _head.Parent = null; } } else { // This is to determine after the current's left replaces current, // it should be the left child or the right child of current's parent node. int result = current.Parent.CompareTo(current.Value); if (result > 0) { // if parent value is greater than current value // make the current's left child a left child of parent current.Parent.Left = current.Left; } else if (result < 0) { // if parent value is less than current value // make the current's left child a right child of parent current.Parent.Right = current.Left; } } } // Case 2: If current's right child has no left child, then current's // right child replaces current // first we move current's left child to its right child's left child since it has no left child. // the reason we can do this is because current's right must be bigger than current, but // current's left must be smaller than current, so it's safe to make such move. else if (current.Right.Left == null) { current.Right.Left = current.Left; if (current.Parent == null) { _head = current.Right; if (_head != null) { _head.Parent = null; } } else { int result = current.Parent.CompareTo(current.Value); if (result > 0) { // if parent value is greater than current value // make the current's right child a left child of parent current.Parent.Left = current.Right; } else if (result < 0) { // if parent value is less than current value // make the current right child a right child of parent current.Parent.Right = current.Right; } } } // Case 3: current's right has a left child, then replace current with current's // right child's left-most child. // Seems complicated but the reason is actually straightforward. // Current's right must be bigger than current, and current's right's left-most node // must be the least bigger value compared to current, so it needs to be replaced by // that value. else { // Find the right's left-most child // start with current.Right.Left as first AVLTreeNode <T> leftmost = current.Right.Left; while (leftmost.Left != null) { leftmost = leftmost.Left; } // if the leftmost node has a right child, make that right child // as leftmost's parent's left child leftmost.Parent.Left = leftmost.Right; // assign leftmost's left and right to current's left and right children leftmost.Left = current.Left; leftmost.Right = current.Right; if (current.Parent == null) { _head = leftmost; if (_head != null) { _head.Parent = null; } } else { int result = current.Parent.CompareTo(current.Value); if (result > 0) { // if parent value is greater than current value // make leftmost the parent's left child current.Parent.Left = leftmost; } else if (result < 0) { // if parent value is less than current value // make leftmost the parent's right child current.Parent.Right = leftmost; } } } // Removal done, need to consider balancing if (treeToBalance != null) { treeToBalance.Balance(); } else { if (_head != null) { _head.Balance(); } } return(true); }
//Vi node la dai luong nguoi dung khoi tao nen cac phep toan so sanh phari duoc cai dat public int CompareTo(object obj) { AVLTreeNode <T> node = obj as AVLTreeNode <T>; return(this.Value.CompareTo(node.Value)); }
private AVLTreeNode <T> Remove(AVLTreeNode <T> node, T value) { //Neu cay rong if (node == null) { return(null); } else { AVLTreeNode <T> parent = new AVLTreeNode <T>(value); if (node.Value.CompareTo(value) > 0)//Truong hop gia tri can xoa nho hon node dang xet->tim tren cay con trai { node.LeftChild = Remove(node.LeftChild, value); if (balance_factor(node) == -2)//Cay lech phai { if (balance_factor(node.RightChild) <= 0) { node = RotateRR(node); } else { node = RotateRL(node); } } } else if (node.Value.CompareTo(value) < 0)//Truong hop gia tri can xoa lon hon node dang xet->tim tren cayy con phai { node.RightChild = Remove(node.RightChild, value); if (balance_factor(node) == 2)//Cay lech trai { if (balance_factor(node.LeftChild) >= 0) { node = RotateLL(node); } else { node = RotateLR(node); } } } ///Neu tim duoc nodee can xet else { if (node.RightChild != null) { //delete its inorder successor parent = node.RightChild; while (parent.LeftChild != null) { parent = parent.LeftChild; } node.Value = parent.Value; //Gan lai gia tri node hien hanh node.RightChild = Remove(node.RightChild, parent.Value); if (balance_factor(node) == 2) //Tai can bang cay { if (balance_factor(node.LeftChild) >= 0) { node = RotateLL(node); } else { node = RotateLR(node); } } } else { //if node.left != null return(node.LeftChild); } } } return(node); }
private bool CheckRemove(AVLTreeNode <T> node, T value) { if (node == null) { return(false); } if (node.Value.Equals(value)) { if (node.IsLeaf) // no children { if (node.Parent.LeftChild == node) { node.Parent.LeftChild = null; } else { node.Parent.RightChild = null; } node.Parent = null; } else if (node.CheckLeftChild && node.CheckRightChild) // 2 children { // Tìm successor node AVLTreeNode <T> replacementNode = node.RightChild; while (replacementNode.CheckLeftChild) { replacementNode = replacementNode.LeftChild; } node.Value = replacementNode.Value; Remove(replacementNode, replacementNode.Value); } else // one child { AVLTreeNode <T> subNode; if (node.CheckLeftChild) { subNode = node.LeftChild; } else { subNode = node.RightChild; } if (Root == (subNode)) { Root = subNode; } subNode.Parent = node.Parent; if (node.Parent.LeftChild == node) { node.Parent.LeftChild = subNode; } else { node.Parent.RightChild = subNode; } } return(true); } else { if (node.Value.CompareTo(value) > 0) { return(CheckRemove(node.LeftChild, value)); } else { return(CheckRemove(node.RightChild, value)); } } }
/// <summary> /// Removes the first occurance of the specified value from the tree. /// </summary> /// <param name="value">The value to remove</param> /// <returns>True if the value was removed, false otherwise</returns> public bool Remove(T value) { var current = Find(value); if (current == null) { return(false); } var treeToBalance = current.Parent; Count--; // Case 1: If current has no right child, then current's left replaces current if (current.Right == null) { if (current.Parent == null) { _head = current.Left; if (_head != null) { _head.Parent = null; } } else { var result = current.Parent.CompareTo(current.Value); if (result > 0) { // if parent value is greater than current value make the current left child a left child of parent current.Parent.Left = current.Left; } else if (result < 0) { // if parent value is less than current value make the current left child a right child of parent current.Parent.Right = current.Left; } } } // Case 2: If current's right child has no left child, then current's right child // replaces current else if (current.Right.Left == null) { current.Right.Left = current.Left; if (current.Parent == null) { _head = current.Right; if (_head != null) { _head.Parent = null; } } else { var result = current.Parent.CompareTo(current.Value); if (result > 0) { // if parent value is greater than current value make the current right child a left child of parent current.Parent.Left = current.Right; } else if (result < 0) { // if parent value is less than current value make the current right child a right child of parent current.Parent.Right = current.Right; } } } // Case 3: If current's right child has a left child, replace current with current's // right child's left-most child else { // find the right's left-most child var leftmost = current.Right.Left; while (leftmost.Left != null) { leftmost = leftmost.Left; } // the parent's left subtree becomes the leftmost's right subtree leftmost.Parent.Left = leftmost.Right; // assign leftmost's left and right to current's left and right children leftmost.Left = current.Left; leftmost.Right = current.Right; if (current.Parent == null) { _head = leftmost; if (_head != null) { _head.Parent = null; } } else { var result = current.Parent.CompareTo(current.Value); if (result > 0) { // if parent value is greater than current value make leftmost the parent's left child current.Parent.Left = leftmost; } else if (result < 0) { // if parent value is less than current value make leftmost the parent's right child current.Parent.Right = leftmost; } } } if (treeToBalance != null) { treeToBalance.Balance(); } else { _head?.Balance(); } return(true); }
public AVLTreeNode(TNode value, AVLTreeNode <TNode> parent, AVLTree <TNode> tree) { Value = value; Parent = parent; _tree = tree; }
public bool Remove(T value) { var compare = value.CompareTo(Value); if (compare == 0) { if (LeftHand == null && RightHand == null) { if (Parent != null) { if (Parent.LeftHand == this) { Parent.LeftHand = null; } else { Parent.RightHand = null; } Parent.Reconstruct(true); } else { AVLTree.RootNode = null; } } else { if (LeftHand == null || RightHand == null) { AVLTreeNode child = LeftHand ?? RightHand; if (Parent != null) { if (Parent.LeftHand == this) { Parent.LeftHand = child; } else { Parent.RightHand = child; } child.Parent = Parent; child.Parent.Reconstruct(true); } else { AVLTree.RootNode = child; AVLTree.RootNode.Parent = null; } } else { AVLTreeNode replace = LeftHand; while (replace.RightHand != null) { replace = replace.RightHand; } T tempValue = Value; Value = replace.Value; replace.Value = tempValue; return(replace.Remove(replace.Value)); } } Parent = LeftHand = RightHand = null; return(true); } if (compare < 0) { return(LeftHand == null ? false : LeftHand.Remove(value)); } else { return(RightHand == null ? false : RightHand.Remove(value)); } }
void Reconstruct(bool recursive) { Count = 1; int leftLevel = 0; int rightLevel = 0; if (LeftHand != null) { leftLevel = LeftHand.Level; Count += LeftHand.Count; } if (RightHand != null) { rightLevel = RightHand.Level; Count += RightHand.Count; } if (leftLevel - rightLevel > 1) { int leftNext = LeftHand.LeftHand == null ? 0 : LeftHand.LeftHand.Level; int rightNext = LeftHand.RightHand == null ? 0 : LeftHand.RightHand.Level; if (leftNext >= rightNext) { LeftHand.Elevate(); Reconstruct(true); } else { AVLTreeNode pivot = LeftHand.RightHand; pivot.Elevate(); pivot.Elevate(); pivot.LeftHand.Reconstruct(false); pivot.RightHand.Reconstruct(true); } } else if (rightLevel - leftLevel > 1) { int leftNext = RightHand.LeftHand == null ? 0 : RightHand.LeftHand.Level; int rightNext = RightHand.RightHand == null ? 0 : RightHand.RightHand.Level; if (rightNext >= leftNext) { RightHand.Elevate(); Reconstruct(true); } else { var pivot = RightHand.LeftHand; pivot.Elevate(); pivot.Elevate(); pivot.LeftHand.Reconstruct(false); pivot.RightHand.Reconstruct(true); } } else { Level = Math.Max(leftLevel, rightLevel) + 1; if (Parent != null && recursive) { Parent.Reconstruct(true); } } }