static void RLRotation(TLDNode *x, TLDList *tld) { TLDNode *k1, *k2, *k3, *p; k1 = x; k3 = k1->right; k2 = k3->left; p = k1->parent; doubleRotate(k1,k2,k3,p, p != NULL && isLeftChild(k1), tld); }
BinaryNode::~BinaryNode(){ // Since we automatically make connections when we use // the setXChild methods, we need to clean up the ties if(hasParent()){ if(isLeftChild()){ parent->leftChild = NULL; } else{ parent->rightChild = NULL; } } }
size_t StatusStructure::getLeftNeighbourIndex(size_t index) const { size_t currentIndex = index; if (leftChild(currentIndex) != nullptr) { // if there is a left sub tree find the most right leaf in that tree currentIndex = getLeftChildIndex(currentIndex); while (rightChild(currentIndex) != nullptr) { currentIndex = getRightChildIndex(currentIndex); } return currentIndex; } // the root element can't be the right child of another element if (currentIndex == 0) { return index; } if (!isLeftChild(currentIndex)) { // current element is the right child of its parent... hence the parent is the left neighbour return getParentIndex(currentIndex); } // current element is the left child of its parent... traverse upwards to the first node that is not a left child or the root node while (currentIndex > 0 && isLeftChild(currentIndex)) { currentIndex = getParentIndex(currentIndex); } if (currentIndex == 0) { return index; } // the fragment at currentIndex is right of its parent and the fragment that // we started with is the most left child of this fragment... hence the parent is // the direct left neighbour currentIndex = getParentIndex(currentIndex); return currentIndex; }
size_t StatusStructure::getRightNeighbourIndex(size_t index) const { size_t currentIndex = index; if (rightChild(currentIndex) != nullptr) { // if there is a right sub tree find the most left leaf in that tree currentIndex = getRightChildIndex(currentIndex); while (leftChild(currentIndex) != nullptr) { currentIndex = getLeftChildIndex(currentIndex); } return currentIndex; } // the root element can't be the left child of another element if (currentIndex == 0) { return index; } if (isLeftChild(currentIndex)) { // current element is the left child of its parent... hence the parent is the right neighbour return getParentIndex(currentIndex); } // current element is the right child of its parent... traverse upwards to the first node that is not a right child or the root node while (currentIndex > 0 && !isLeftChild(currentIndex)) { currentIndex = getParentIndex(currentIndex); } if (currentIndex == 0) { return index; } currentIndex = getParentIndex(currentIndex); return currentIndex; }
TreeNode *inOrderSuccessor(TreeNode *node) { if (!node) { return NULL; } if (node->right) { return leftMostNode(node->right); } TreeNode *parent = node->parent; while (parent && !isLeftChild(node, parent)) { node = parent; parent = node->parent; } return parent; }
static void RRRotation(TLDNode *x, TLDList *tld) { TLDNode *k1 = x; TLDNode *k2 = x->right; TLDNode *p = k1->parent; if (p == NULL) { tld->root = k2; k2->parent = NULL; } else if (isLeftChild(k1)) p->left = k2; else p->right = k2; k1->right = k2->left; updateParent(k1, k2->left); k1->parent = k2; k2->parent = p; k2->left = k1; updateHeight(k1); }
static void LLRodation(TLDNode *x, TLDList *tld) { TLDNode *k2 = x; TLDNode *k1 = k2->left; TLDNode *p = k2->parent; if (p == NULL) { tld->root = k1; k1->parent = NULL; } else if (isLeftChild(k2)) p->left = k1; else p->right = k1; k2->left = k1->right; updateParent(k2, k1->right); k2->parent = k1; k1->parent = p; k1->right = k2; updateHeight(k2); }
void RbTreeUtil::remove(RbTreeAnchor *tree, RbTreeNode *node) { BSLS_ASSERT(0 != node); BSLS_ASSERT(0 != tree); BSLS_ASSERT(0 != tree->rootNode()); RbTreeNode *x, *y; RbTreeNode *parentOfX; bool yIsBlackFlag; // Implementation Note: This implementation has been adjusted from the // one described in "Introduction to Algorithms" [Cormen, Leiserson, // Rivest] (i.e., CLR) to avoid swapping node values (swapping nodes is // potentially inefficient and inappropriate for an STL map). // Specifically, int case where 'node' has two (non-null) children, CLR // (confusingly) swaps the value of the node with its replacement; instead // we move node's successor to the position of node, and then recolor its // value with the same result). // Case 1: If either child of the node being removed is 0, then 'node' can // be replaced by its non-null child (or by a null child if 'node' has no // children). if (0 == node->leftChild()) { y = node; x = node->rightChild(); } else if (0 == node->rightChild()) { y = node; x = node->leftChild(); } else { // Case 2: Otherwise the 'node' will be replaced by its successor in // the tree. y = leftmost(node->rightChild()); x = y->rightChild(); } yIsBlackFlag = y->isBlack(); if (y == node) { // We should be in case 1, where 'node' has (at least 1) null child, // and will simply be replaced by one of its children. In this // context, 'x' refers to the node that will replace 'node'. Simply // point the parent of 'node' to its new child, 'x'. Note that in // this context, we may have to set the first and last node of the // tree. BSLS_ASSERT_SAFE(0 == node->leftChild() || 0 == node->rightChild()); if (isLeftChild(node)) { // If the node being removed is to the left of its parent, it may // be the first node of the tree. if (node == tree->firstNode()) { tree->setFirstNode(next(node)); } node->parent()->setLeftChild(x); } else { node->parent()->setRightChild(x); } parentOfX = node->parent(); if (x) { x->setParent(node->parent()); } } else { // We should be in case 2, where 'node' has two non-null children. In // this context 'y' is the successor to 'node' which will be used to // replace 'node'. Note that in this context, we never need to set // the first or last node of the tree (as the node being removed has // two children). BSLS_ASSERT_SAFE(0 != node->leftChild() && 0 != node->rightChild()); BSLS_ASSERT_SAFE(0 == y->leftChild()); BSLS_ASSERT_SAFE(x == y->rightChild()); if (isLeftChild(node)) { node->parent()->setLeftChild(y); } else { node->parent()->setRightChild(y); } y->setLeftChild(node->leftChild()); y->leftChild()->setParent(y); if (y->parent() != node) { // The following logic only applies if the replacement node 'y' is // not a direct descendent of the 'node' being replaced, otherwise // it is a degenerate case. BSLS_ASSERT_SAFE(y->parent()->leftChild() == y); parentOfX = y->parent(); y->parent()->setLeftChild(x); // 'x' is y->rightChild() if (x) { x->setParent(y->parent()); } y->setRightChild(node->rightChild()); y->rightChild()->setParent(y); } else { parentOfX = y; } y->setParent(node->parent()); y->setColor(node->color()); } if (yIsBlackFlag) { recolorTreeAfterRemoval(tree, x, parentOfX); } BSLS_ASSERT(!tree->rootNode() || tree->sentinel() == tree->rootNode()->parent()); tree->decrementNumNodes(); }
void RbTreeUtil::insertAt(RbTreeAnchor *tree, RbTreeNode *parentNode, bool leftChildFlag, RbTreeNode *newNode) { BSLS_ASSERT(parentNode); BSLS_ASSERT(newNode); BSLS_ASSERT(tree); newNode->setLeftChild(0); newNode->setRightChild(0); // Insert the node as a leaf in the tree, and assign its parent // pointer. newNode->makeRed(); newNode->setParent(parentNode); if (leftChildFlag) { parentNode->setLeftChild(newNode); if (parentNode == tree->firstNode()) { tree->setFirstNode(newNode); } } else { parentNode->setRightChild(newNode); } // Fix the tree coloring (if necessary). // Implementation Note: The following is adapted with few changes from // "Introduction to Algorithms" [Cormen, Leiserson, Rivest] , except that // explicit conditions are required to treat NULL values as Black, and // consequently to avoid setting a color (BLACK) on a (already BLACK) null // node. RbTreeNode *node = newNode; while (node != tree->rootNode() && node->parent()->isRed()) { if (isLeftChild(node->parent())) { RbTreeNode *uncle = node->parent()->parent()->rightChild(); // Test if 'uncle' is BLACK (0 is considered BLACK) if (uncle && uncle->isRed()) { // Case 1: grandParent[node] -> (X:B) // / \. // parent[node]- > (Y:R) (uncle:R) // / // (node:R) node->parent()->parent()->makeRed(); node->parent()->makeBlack(); uncle->makeBlack(); node = node->parent()->parent(); } else { if (isRightChild(node)) { // Case 2: grandParent[node] -> (X:B) // / \. // parent[node]- > (Y:R) (uncle:B) // \. // (node:R) // // Perform a left rotation on parent[node] to reduce to // case 3. node = node->parent(); rotateLeft(node); } // Case 3: grandParent[node] -> (X:B) // / \. // parent[node]- > (Y:R) (uncle:B) // / // (node:R) // // Recolor the parent black, the grand parent-red, then rotate // the grand-parent right, so that its the new root of the // sub-tree. node->parent()->makeBlack(); node->parent()->parent()->makeRed(); rotateRight(node->parent()->parent()); } } else { // The following mirrors the cases above, but with right and left // exchanged. RbTreeNode *uncle = node->parent()->parent()->leftChild(); if (uncle && uncle->isRed()) { node->parent()->parent()->makeRed(); node->parent()->makeBlack(); uncle->makeBlack(); node = node->parent()->parent(); } else { if (isLeftChild(node)) { node = node->parent(); rotateRight(node); } node->parent()->makeBlack(); node->parent()->parent()->makeRed(); rotateLeft(node->parent()->parent()); } } } BSLS_ASSERT(tree->sentinel() == tree->rootNode()->parent()); tree->rootNode()->makeBlack(); tree->incrementNumNodes(); }