/* * After an insertion, possibly rebalance the tree so that the left and right * node heights don't differ by more than 1. * May update *node. */ static void avlAdjustBalance(avl_tree *tree, avl_node **node) { avl_node *current = *node; int b = avlBalance(current) / 2; if (b != 0) { int dir = (1 - b) / 2; if (avlBalance(current->children[dir]) == -b) avlRotate(¤t->children[dir], !dir); current = avlRotate(node, dir); } if (current != tree->end) avlUpdateHeight(current); }
//Recursively prints the tree - used for debugging void printTree( AvlNode *node, int depth, int left ) { //base case if( node == NULL ) return; //print space so you can tell how deep this node is int i; for( i = 0; i < depth; i++ ) { printf( " " ); } //print whether this was a left or right subchild printf( left ? "L: " : "R: " ); //print data for the node printf( "%s height:%d balance:%d\n", node->data, node->height, avlBalance( node ) ); //recurse on children printTree( node->left, depth + 1, 1 ); printTree( node->right, depth + 1, 0 ); }
//Finds the right spot for the word in question //and adds a node to the tree if necessary. //Returns the new tree from this node down. //Also sets the global avlFindAddReturn to //the word's corresponding node. AvlNode *avlFindAdd( AvlNode *from, char *newData ) { //If the current node is null, a new node //must be created and returned if( from == NULL ) { AvlNode *out = avlNew( newData ); avlFindAddReturn = out; avlFindAddNodeAdded = 1; return out; } //Compare the word we're looking for to the word //at this node int comp; AvlNode *toAdd; comp = strcmp( newData, from->data ); //Update the left or right subtree to ensure //it includes a node for this word. If the word //is in this node, set bstFindAddReturn to this node. if( comp < 0 ) { from->left = avlFindAdd( from->left, newData ); } else if( comp > 0 ) { from->right = avlFindAdd( from->right, newData ); } else { avlFindAddReturn = from; } //If a node was added, some things need to be done. if( avlFindAddNodeAdded ) { //Update the height avlSetHeight( from ); int balance = avlBalance( from ); //If the balance factor at this node is //2 or -2, a rebalance must be done to //conform to AVL. if( balance == -2 ) { AvlNode *node2, *node3; if( avlBalance( from->left ) == -1 ) { //left-left node2 = from->left; from->left = node2->right; node2->right = from; avlSetHeight( from ); avlSetHeight( node2 ); return node2; } else { //left-right node2 = from->left; node3 = node2->right; from->left = node3->right; node2->right = node3->left; node3->left = node2; node3->right = from; avlSetHeight( from ); avlSetHeight( node2 ); avlSetHeight( node3 ); return node3; } } else if( balance == 2 ) { AvlNode *node2, *node3; if( avlBalance( from->right ) == 1 ) { //right-right node2 = from->right; from->right = node2->left; node2->left = from; avlSetHeight( from ); avlSetHeight( node2 ); return node2; } else { //right-left node2 = from->right; node3 = node2->left; from->right = node3->left; node2->left = node3->right; node3->right = node2; node3->left = from; avlSetHeight( from ); avlSetHeight( node2 ); avlSetHeight( node3 ); return node3; } } } //if no balances occured, this node //remains the root of this subtree return from; }