//O(N) private List <T> InOrderTraverseFullInfo(AVLTreeNodeCPC <T> node) { var result = new List <T>(); if (node.leftChild != null) { result.AddRange(InOrderTraverseFullInfo(node.leftChild)); } result.Add(node.data); Console.WriteLine("Node: {0}, Weight: {7}, Parent: {1}, LeftChild: {2}, RightChild: {3}, LeftHeight: {4}, RightHeight: {5}, ChildrenNum: {6}", node.data.ToString(), node.parent == null ? "null" : node.parent.data.ToString(), node.leftChild == null ? "null" : node.leftChild.data.ToString(), node.rightChild == null ? "null" : node.rightChild.data.ToString(), node.leftHeight, node.rightHeight, node.childrenNum, node.weight); if (node.rightChild != null) { result.AddRange(InOrderTraverseFullInfo(node.rightChild)); } return(result); }
private void Rotate(AVLTreeNodeCPC <T> parent, bool isChildLeft, bool isGrandchildLeft) { try { if (isChildLeft && isGrandchildLeft) { RightRotate(parent); } else if (isChildLeft && !isGrandchildLeft) { LeftRightRotate(parent); } else if (!isChildLeft && isGrandchildLeft) { RightLeftRotate(parent); } else if (!isChildLeft && !isGrandchildLeft) { LeftRotate(parent); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } }
private void MinusParentChildrenNum(AVLTreeNodeCPC <T> node) { var parent = node.parent; while (parent != null) { parent.childrenNum--; parent = parent.parent; } }
private void UpdateChildrenNumberByDirectChildren(AVLTreeNodeCPC <T> parent) { parent.childrenNum = 0; if (parent.leftChild != null) { parent.childrenNum += parent.leftChild.childrenNum + parent.leftChild.weight; } if (parent.rightChild != null) { parent.childrenNum += parent.rightChild.childrenNum + parent.rightChild.weight; } }
//O(N) private List <T> InOrderTraverse(AVLTreeNodeCPC <T> node) { var result = new List <T>(); if (node.leftChild != null) { result.AddRange(InOrderTraverse(node.leftChild)); } result.Add(node.data); if (node.rightChild != null) { result.AddRange(InOrderTraverse(node.rightChild)); } return(result); }
private void RightRotate(AVLTreeNodeCPC <T> parent) { //parent must have a left child var newParent = parent.leftChild; //1. Update each node's parent newParent.parent = parent.parent; parent.parent = newParent; if (parent.leftChild.rightChild != null) { parent.leftChild.rightChild.parent = parent; } //2. Update each node's child parent.leftChild = parent.leftChild.rightChild; newParent.rightChild = parent; //3. Update height if (parent.leftChild != null) { parent.leftHeight = Math.Max(parent.leftChild.leftHeight, parent.leftChild.rightHeight) + 1; } else { parent.leftHeight = 0; } newParent.rightHeight = Math.Max(parent.leftHeight, parent.rightHeight) + 1; //4. Update children number UpdateChildrenNumberByDirectChildren(parent); UpdateChildrenNumberByDirectChildren(newParent); //5. Update new parent's parent if (newParent.parent == null) { root = newParent; } else if (newParent.parent.leftChild == parent) { newParent.parent.leftChild = newParent; } else { newParent.parent.rightChild = newParent; } }
private int CheckChildrenNum(AVLTreeNodeCPC <T> node) { var currentNode = node; while (currentNode != null) { var left = CheckChildrenNum(currentNode.leftChild); var right = CheckChildrenNum(currentNode.rightChild); if (left + right == currentNode.childrenNum) { return(currentNode.childrenNum + currentNode.weight); } else { Console.WriteLine("Node {0} has wrong children number", currentNode.data); return(-1); } } return(0); }
private AVLTreeNodeCPC <T> GetNextInOrderNode(AVLTreeNodeCPC <T> node) { if (node.rightChild != null) { var currentNode = node.rightChild; while (true) { if (currentNode.leftChild != null) { currentNode = currentNode.leftChild; } else { return(currentNode); } } } return(null); }
private void MinusParentChildrenNum(AVLTreeNodeCPC <T> node, AVLTreeNodeCPC <T> endNode, int weight) { var parent = node.parent; bool hasReachedEndNode = false; while (parent != null) { if (parent == endNode) { hasReachedEndNode = true; } if (hasReachedEndNode) { parent.childrenNum--; } else { parent.childrenNum -= weight; } parent = parent.parent; } }
private void RightLeftRotate(AVLTreeNodeCPC <T> parent) { //parent must have a right child and a right-left grandchild RightRotate(parent.rightChild); LeftRotate(parent); }
private void LeftRightRotate(AVLTreeNodeCPC <T> parent) { //parent must have a left child and a left-right grandchild LeftRotate(parent.leftChild); RightRotate(parent); }
private void BalanceNode(AVLTreeNodeCPC <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; } }
private bool RemoveDataFromNode(T data, AVLTreeNodeCPC <T> node, bool isLeft) { if (!node.subTree.RemoveNode(data)) { //Cannot find the node in subtree Console.WriteLine("Unable to find {0} in subtree", data); return(false); } if (node.weight > 1) { 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; node.subTree = nextNode.subTree; 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); }
//O(LogN) public bool InsertNode(T data) { try { var newNode = new AVLTreeNodeCPC <T>() { data = data, subTree = new AVLBST <T>(subComparison) }; newNode.subTree.InsertNode(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++; currentNode.subTree.InsertNode(data); return(true); } } BalanceNode(newNode); return(true); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } return(false); }