/*
 * 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;
}
Exemple #2
0
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;
}