Example #1
0
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;
}
Example #5
0
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;
}
Example #6
0
 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);
 }
Example #7
0
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);
 }
Example #8
0
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();
}
Example #9
0
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();
}