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); }
static TNode *insertBalance(TNode *root, int dir) { TNode *n = root->link[dir]; int bal = (dir == 0) ? -1 : +1; if (n->balance == bal) { root->balance = n->balance = 0; root = singleRotate(root, !dir); } else { /* n->balance == -bal */ adjustBalance(root, dir, bal); root = doubleRotate(root, !dir); } return root; }
static TNode *removeBalance(TNode *root, int dir, int *done) { TNode *n = root->link[!dir]; int bal = (dir == 0) ? -1 : +1; if (n->balance == -bal) { root->balance = n->balance = 0; root = singleRotate(root, dir); } else if (n->balance == bal) { adjustBalance(root, !dir, -bal); root = doubleRotate(root, dir); } else { /* n->balance == 0 */ root->balance = -bal; n->balance = bal; root = singleRotate(root, dir); *done = 1; } return root; }
/** * Rebalances an AVL tree. * This function should be called with either walkPtr OR walkSRPPtr set. * Use walkPtr if you have a direct pointer to the node or walkSRPPtr if you have a pointer to a WSRP * * @param[in] tree The tree * @param[in] walkPtr A pointer to the root of the tree to balance (walkSRPPtr is NULL) * @param[in] walkSRPPtr A pointer to an SRP of the root of the tree to balance (walkPtr is NULL) * @param[in|out] heightChange The height change */ static void rebalance(J9AVLTree *tree, J9AVLTreeNode **walkPtr, J9WSRP *walkSRPPtr, intptr_t direction, intptr_t *heightChange) { J9AVLTreeNode *walk = NULL; uintptr_t walkBalance; if (!(*heightChange)) { return; } Trc_AVL_rebalance_Entry(tree, walkPtr, walkSRPPtr, direction, heightChange); /* if we shrunk nodes, flip the direction, thus direction points towards heavy direction */ if (*heightChange < 0) { direction = -direction; } /* Assumption is that if walkSRPPtr is NULL, walkPtr is not */ if (!walkSRPPtr) { walk = AVL_GETNODE(*walkPtr); } else { walk = AVL_NNSRP_GETNODE(*walkSRPPtr); } walkBalance = AVL_GETBALANCE(walk); if (walkBalance == AVL_BALANCED) { AVL_SETBALANCE(walk, (direction < 0) ? AVL_LEFTHEAVY : AVL_RIGHTHEAVY); /* if the tree was shrinking, we've just unbalanced a node .. no longer shrinking */ if (*heightChange < 0) { *heightChange = 0; } } else if ((walkBalance == AVL_LEFTHEAVY) == (direction < 0)) { J9AVLTreeNode *rotateResult = NULL; /* left heavy adding to the left or right heavy adding to the right */ if ((direction < 0) && (AVL_GETBALANCE(AVL_NNSRP_GETNODE(walk->leftChild)) == AVL_RIGHTHEAVY)) { /* doubleRotate */ rotateResult = (J9AVLTreeNode *)doubleRotate(tree, walk, -direction, heightChange); } else if ((direction > 0) && (AVL_GETBALANCE(AVL_NNSRP_GETNODE(walk->rightChild)) == AVL_LEFTHEAVY)) { /* doubleRotate */ rotateResult = (J9AVLTreeNode *)doubleRotate(tree, walk, -direction, heightChange); } else { /* single rotate */ rotateResult = (J9AVLTreeNode *)rotate(tree, walk, -direction, heightChange); } /* Assumption is that if walkSRPPtr is NULL, walkPtr is not */ if (!walkSRPPtr) { AVL_SETNODE(*walkPtr, rotateResult); } else { AVL_NNSRP_PTR_SETNODE(walkSRPPtr, rotateResult); } } else { AVL_SETBALANCE(walk, AVL_BALANCED); /* added height making node become equal -- no more growing */ if (*heightChange > 0) { *heightChange = 0; } } Trc_AVL_rebalance_Exit(*heightChange); }