/* * rebalance a sub-tree whose right branch has been reduced by one level * because of deletion */ AVLNode * AVL_RebalanceShorterRight(AVLNode * self, int *height_changed) { #ifndef __CXC__ AVLNode *p = self; #else AVLNode *p; p = self; #endif switch (p->balance) { case Equal: p->balance = LeftHigh; *height_changed = 0; break; case RightHigh: /* taller (right) subtree was shortened */ p->balance = Equal; break; case LeftHigh: { /* * shorter (right) sub-tree was shortened, violating * AVL rules */ AVLNode *q; q = p->left; switch (q->balance) { case Equal: *height_changed = 0; q->balance = RightHigh; p = AVL_RotateRight(p); break; case LeftHigh: p->balance = q->balance = Equal; p = AVL_RotateRight(p); break; case RightHigh: p = AVL_DoubleRotateRight(p); break; } break; } } return p; }
treenode *AVL_LeftBalance(treenode * r) { treenode *x; treenode *w; x = r->Lchild; switch (x->bf) { case LH: r->bf = EH; x->bf = EH; r = AVL_RotateRight(r); break; #ifdef AVL_DEBUG case EH: Error(6); break; #endif case RH: w = x->Rchild; switch (w->bf) { case EH: r->bf = EH; x->bf = EH; break; case RH: r->bf = EH; x->bf = LH; break; case LH: r->bf = RH; x->bf = EH; break; } w->bf = EH; x = AVL_RotateLeft(x); r->Lchild = x; r = AVL_RotateRight(r); } return r; }
/* * Rebalance sub-tree whose left branch has become heavier because of * insertion */ AVLNode * AVL_RebalanceHeavierLeft(AVLNode * self, int *height_changed) { #ifndef __CXC__ AVLNode *root = self; #else AVLNode *root; root = self; #endif /* left-subtree has grown by one level */ switch (root->balance) { case RightHigh: root->balance = Equal; *height_changed = 0; break; case Equal: root->balance = LeftHigh; break; case LeftHigh: { #ifndef __CXC__ AVLNode *lf = self->left; #else AVLNode *lf; lf = self->left; #endif switch (lf->balance) { case LeftHigh: self->balance = Equal; lf->balance = Equal; root = AVL_RotateRight(self); break; case RightHigh: root = AVL_DoubleRotateRight(self); break; default: break; } *height_changed = 0; break; } } return root; }
/* doubly rotate sub-tree and return new root (change balance as needed) */ AVLNode * AVL_DoubleRotateLeft(AVLNode * self) { #ifndef __CXC__ AVLNode *rt = self->right; AVLNode *lf = rt->left; AVLNode *root; #else AVLNode *rt; AVLNode *lf; AVLNode *root; rt = self->right; lf = rt->left; #endif switch (lf->balance) { case RightHigh: self->balance = LeftHigh; rt->balance = Equal; break; case Equal: self->balance = rt->balance = Equal; break; case LeftHigh: self->balance = Equal; rt->balance = RightHigh; break; } lf->balance = Equal; AVL_SetRight(self, AVL_RotateRight(rt)); root = AVL_RotateLeft(self); return root; }