private void RightLeftRotate(AVLTreeNode <T> parent) { //parent must have a right child and a right-left grandchild RightRotate(parent.rightChild); LeftRotate(parent); }
private void LeftRightRotate(AVLTreeNode <T> parent) { //parent must have a left child and a left-right grandchild LeftRotate(parent.leftChild); RightRotate(parent); }
private bool RemoveCurrentNode(AVLTreeNode <T> node, bool isLeft, bool removeAll = false) { if (node.weight > 1) { if (removeAll) { for (int i = 0; i < node.weight - 1; i++) { node.weight--; MinusParentChildrenNum(node); } } else { node.weight--; MinusParentChildrenNum(node); return(true); } } if (node.leftChild == null) { var parent = node.parent; if (node.rightChild != null) { node.rightChild.parent = parent; } if (parent == null) { //root node root = node.rightChild; } else { if (isLeft) { parent.leftChild = node.rightChild; } else { parent.rightChild = node.rightChild; } } MinusParentChildrenNum(node); BalanceNode(node.parent); node = null;//Memory Leak?? } else if (node.rightChild == null) { var parent = node.parent; if (node.leftChild != null) { node.leftChild.parent = parent; } if (parent == null) { //root node root = node.leftChild; } else { if (isLeft) { parent.leftChild = node.leftChild; } else { parent.rightChild = node.leftChild; } } MinusParentChildrenNum(node); BalanceNode(node.parent); node = null; } else { //Get the next node in InOrderTraverse var nextNode = GetNextInOrderNode(node); if (nextNode.parent == node) { if (node.parent == null) { //root node root = nextNode; nextNode.parent = null; } else { var parent = node.parent; nextNode.parent = parent; if (isLeft) { parent.leftChild = nextNode; } else { parent.rightChild = nextNode; } } nextNode.leftChild = node.leftChild; if (node.leftChild != null) { node.leftChild.parent = nextNode; nextNode.childrenNum += node.leftChild.childrenNum + node.leftChild.weight; } MinusParentChildrenNum(nextNode); BalanceNode(nextNode); node = null; } else { //Copy the value of nextNode to currentNode, then delete nextNode node.data = nextNode.data; node.weight = nextNode.weight; nextNode.parent.leftChild = nextNode.rightChild; if (nextNode.rightChild != null) { nextNode.rightChild.parent = nextNode.parent; } MinusParentChildrenNum(nextNode, node, nextNode.weight); UpdateChildrenNumberByDirectChildren(node); BalanceNode(nextNode.parent); nextNode = null; } } return(true); }
private void BalanceNode(AVLTreeNode <T> newNode) { if (newNode == null) { return; } var currentNode = newNode; var parent = newNode; var isChildLeft = true; var isGrandchildLeft = true; while (parent != null) { if (parent.leftChild == currentNode) {//Left Child parent.leftHeight = Math.Max(currentNode.leftHeight, currentNode.rightHeight) + 1; } else if (parent.rightChild == currentNode) {//Right Child parent.rightHeight = Math.Max(currentNode.leftHeight, currentNode.rightHeight) + 1; } else {//First time if (parent.leftChild != null) { parent.leftHeight = Math.Max(parent.leftChild.leftHeight, parent.leftChild.rightHeight) + 1; } else { parent.leftHeight = 0; } if (parent.rightChild != null) { parent.rightHeight = Math.Max(parent.rightChild.leftHeight, parent.rightChild.rightHeight) + 1; } else { parent.rightHeight = 0; } } var diff = parent.leftHeight - parent.rightHeight; if (diff >= 2 || diff <= -2) { if (parent.leftHeight > parent.rightHeight) { isChildLeft = true; //The balance of sub tree may be 0 on a deletion. Do not double-rotate in this case. if (parent.leftChild.leftHeight >= parent.leftChild.rightHeight) { isGrandchildLeft = true; } else { isGrandchildLeft = false; } } else { isChildLeft = false; if (parent.rightChild.leftHeight > parent.rightChild.rightHeight) { isGrandchildLeft = true; } else { isGrandchildLeft = false; } } Rotate(parent, isChildLeft, isGrandchildLeft); } currentNode = parent; parent = parent.parent; } }
//O(LogN) public bool InsertNode(T data) { try { var newNode = new AVLTreeNode <T>() { data = data }; if (root == null) { root = newNode; return(true); } var currentNode = root; while (true) { var compareResult = CompareNode(data, currentNode.data); if (compareResult > 0) { currentNode.childrenNum++; if (currentNode.rightChild == null) { currentNode.rightChild = newNode; newNode.parent = currentNode; break; } else { currentNode = currentNode.rightChild; } } else if (compareResult < 0) { currentNode.childrenNum++; if (currentNode.leftChild == null) { currentNode.leftChild = newNode; newNode.parent = currentNode; break; } else { currentNode = currentNode.leftChild; } } else { currentNode.weight++; return(true); } } BalanceNode(newNode); return(true); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } return(false); }