Ejemplo n.º 1
0
struct node* insert(struct node* root, int value)
{

	if(root == NULL){
		return newnode(value);
	}
	if(value < root->data){
		root->left = insert(root->left, value);
	} else {
		root->right = insert(root->right, value);
	}
	root->height = compare(heightof(root->left), heightof(root->right)) + 1;
	
	b = balance(root);
	if(b > 1){ 
		if(value < root->left->data){		//left left
			return rightrotate(root);
		} else {				//left right
			root->left = leftrotate(root->left);
			return rightrotate(root);
		}
	}
	if(b < -1){
		if(value > root->right->data){		//right right
			return leftrotate(root);
		} else {				//right left
			root->right = rightrotate(root->right);
			return leftrotate(root);
		}
	}
	return root;		 
}
Ejemplo n.º 2
0
int balance(struct node* root)
{
	struct node* current = root;
	if(current == NULL)
		return 0;
	return heightof(current->left) - heightof(current->right);
}
Ejemplo n.º 3
0
struct node* rightrotate(struct node *root)
{
	int compare(int, int);
	struct node *sub = root->left;
	struct node *b = sub->right;

	sub->right = root;
	root->left = b;
	root->height = compare(heightof(root->left), heightof(root->right)) + 1;
	sub->height = compare(heightof(sub->left), heightof(sub->right)) + 1;
	return sub;
}
Ejemplo n.º 4
0
/* check a tree's consistency and balancing */
static void avl_checkheights (struct vm_area_struct * tree)
{
    int h, hl, hr;

    if (tree == avl_empty)
        return;
    avl_checkheights(tree->vm_avl_left);
    avl_checkheights(tree->vm_avl_right);
    h = tree->vm_avl_height;
    hl = heightof(tree->vm_avl_left);
    hr = heightof(tree->vm_avl_right);
    if ((h == hl+1) && (hr <= hl) && (hl <= hr+1))
        return;
    if ((h == hr+1) && (hl <= hr) && (hr <= hl+1))
        return;
    printk("%s: avl_checkheights: heights inconsistent\n",avl_check_point);
}
Ejemplo n.º 5
0
/***********************************************************************
 *
 * Method     : ut_avlTreeRebalance
 * Description:
 *    After an insert or remove action this method is called to
 *    rebalance the tree. The insert or remove method will pass the
 *    stack (path to the inserted node).
 * Implementation :
 * History    :
 * Algorithm  :
 *    1st : rewind stack and for ech step check tree heights.
 *    2nd : if heights differ more the 1 then rebalance this level.
 * Bugs       :
 *
 ***********************************************************************/
static void
ut_avlTreeRebalance (
    ut_avlNode **nodeplaces_ptr,
    os_uint32 count)
{
    for ( ; count > 0 ; count--) {
        ut_avlNode *nodeplace = *--nodeplaces_ptr;
        ut_avlNode node = *nodeplace;
        ut_avlNode nodeleft = node->left;
        ut_avlNode noderight = node->right;
        os_uint32 heightleft = heightof(nodeleft);
        os_uint32 heightright = heightof(noderight);
        if ((heightright + 1) < heightleft) {
            ut_avlNode nodeleftleft = nodeleft->left;
            ut_avlNode nodeleftright = nodeleft->right;
            os_uint32 heightleftright = heightof(nodeleftright);
            if (heightof(nodeleftleft) >= heightleftright) {
                node->left = nodeleftright; nodeleft->right = node;
                nodeleft->height = 1 + (node->height = 1 + heightleftright);
                *nodeplace = nodeleft;
            } else {
                nodeleft->right = nodeleftright->left;
                node->left = nodeleftright->right;
                nodeleftright->left = nodeleft;
                nodeleftright->right = node;
                nodeleft->height = node->height = heightleftright;
                nodeleftright->height = heightleft;
                *nodeplace = nodeleftright;
            }
        } else if ((heightleft + 1) < heightright) {
            ut_avlNode noderightright = noderight->right;
            ut_avlNode noderightleft = noderight->left;
            os_uint32 heightrightleft = heightof(noderightleft);
            if (heightof(noderightright) >= heightrightleft) {
                node->right = noderightleft; noderight->left = node;
                noderight->height = 1 + (node->height = 1 + heightrightleft);
                *nodeplace = noderight;
            } else {
                noderight->left = noderightleft->right;
                node->right = noderightleft->left;
                noderightleft->right = noderight;
                noderightleft->left = node;
                noderight->height = node->height = heightrightleft;
                noderightleft->height = heightright;
                *nodeplace = noderightleft;
            }
        } else {
            os_uint32 height;
            if (heightleft<heightright) {
                height = heightright+1;
            } else {
                height = heightleft+1;
            }
            if (height == node->height) {
                break;
            }
            node->height = height;
        }
    }
}
Ejemplo n.º 6
0
/***********************************************************************
 *
 * Method     : d_avlTreeRebalance
 * Description:
 *    After an insert or remove action this method is called to
 *    rebalance the tree. The insert or remove method will pass the
 *    stack (path to the inserted node).
 * Algorithm  :
 *    1st : rewind stack and for ech step check tree heights.
 *    2nd : if heights differ more the 1 then rebalance this level.
 *
 ***********************************************************************/
static void
d_avlTreeRebalance (
    d_avlNode ** nodeplaces_ptr,
    c_long       count )
{
    d_avlNode * nodeplace;
    d_avlNode   node;
    d_avlNode   nodeleft;
    d_avlNode   noderight;
    c_long      heightleft;
    c_long      heightright;
    d_avlNode   nodeleftleft;
    d_avlNode   nodeleftright;
    c_long      heightleftright;
    d_avlNode   noderightright;
    d_avlNode   noderightleft;
    c_long      heightrightleft;
    c_long      height;

    for ( ; count > 0 ; count--) {
        nodeplace = *--nodeplaces_ptr;
        node = *nodeplace;
        nodeleft = node->left;
        noderight = node->right;
        heightleft = heightof(nodeleft);
        heightright = heightof(noderight);
        if ((heightright + 1) < heightleft) {
            nodeleftleft = nodeleft->left;
            nodeleftright = nodeleft->right;
            heightleftright = heightof(nodeleftright);
            if (heightof(nodeleftleft) >= heightleftright) {
                node->left = nodeleftright;
                nodeleft->right = node;
                nodeleft->height = 1 + (node->height = 1 + heightleftright);
                *nodeplace = nodeleft;
            } else {
                nodeleft->right = nodeleftright->left;
                node->left = nodeleftright->right;
                nodeleftright->left = nodeleft;
                nodeleftright->right = node;
                nodeleft->height = node->height = heightleftright;
                nodeleftright->height = heightleft;
                *nodeplace = nodeleftright;
            }
        } else if ((heightleft + 1) < heightright) {
            noderightright = noderight->right;
            noderightleft = noderight->left;
            heightrightleft = heightof(noderightleft);
            if (heightof(noderightright) >= heightrightleft) {
                node->right = noderightleft;
                noderight->left = node;
                noderight->height = 1 + (node->height = 1 + heightrightleft);
                *nodeplace = noderight;
            } else {
                noderight->left = noderightleft->right;
                node->right = noderightleft->left;
                noderightleft->right = noderight;
                noderightleft->left = node;
                noderight->height = node->height = heightrightleft;
                noderightleft->height = heightright;
                *nodeplace = noderightleft;
            }
        } else {
            if (heightleft<heightright) {
                height = heightright+1;
            } else {
                height = heightleft+1;
            }
            if (height == node->height) {
                break;
            }
            node->height = height;
        }
    }
}
Ejemplo n.º 7
0
static void avl_rebalance (struct vm_area_struct *** nodeplaces_ptr, int count)
{
    for ( ; count > 0 ; count--) {
        struct vm_area_struct ** nodeplace = *--nodeplaces_ptr;
        struct vm_area_struct * node = *nodeplace;
        struct vm_area_struct * nodeleft = node->vm_avl_left;
        struct vm_area_struct * noderight = node->vm_avl_right;
        int heightleft = heightof(nodeleft);
        int heightright = heightof(noderight);
        if (heightright + 1 < heightleft) {
            /*                                                      */
            /*                            *                         */
            /*                          /   \                       */
            /*                       n+2      n                     */
            /*                                                      */
            struct vm_area_struct * nodeleftleft = nodeleft->vm_avl_left;
            struct vm_area_struct * nodeleftright = nodeleft->vm_avl_right;
            int heightleftright = heightof(nodeleftright);
            if (heightof(nodeleftleft) >= heightleftright) {
                /*                                                        */
                /*                *                    n+2|n+3            */
                /*              /   \                  /    \             */
                /*           n+2      n      -->      /   n+1|n+2         */
                /*           / \                      |    /    \         */
                /*         n+1 n|n+1                 n+1  n|n+1  n        */
                /*                                                        */
                node->vm_avl_left = nodeleftright; nodeleft->vm_avl_right = node;
                nodeleft->vm_avl_height = 1 + (node->vm_avl_height = 1 + heightleftright);
                *nodeplace = nodeleft;
            } else {
                /*                                                        */
                /*                *                     n+2               */
                /*              /   \                 /     \             */
                /*           n+2      n      -->    n+1     n+1           */
                /*           / \                    / \     / \           */
                /*          n  n+1                 n   L   R   n          */
                /*             / \                                        */
                /*            L   R                                       */
                /*                                                        */
                nodeleft->vm_avl_right = nodeleftright->vm_avl_left;
                node->vm_avl_left = nodeleftright->vm_avl_right;
                nodeleftright->vm_avl_left = nodeleft;
                nodeleftright->vm_avl_right = node;
                nodeleft->vm_avl_height = node->vm_avl_height = heightleftright;
                nodeleftright->vm_avl_height = heightleft;
                *nodeplace = nodeleftright;
            }
        }
        else if (heightleft + 1 < heightright) {
            /* similar to the above, just interchange 'left' <--> 'right' */
            struct vm_area_struct * noderightright = noderight->vm_avl_right;
            struct vm_area_struct * noderightleft = noderight->vm_avl_left;
            int heightrightleft = heightof(noderightleft);
            if (heightof(noderightright) >= heightrightleft) {
                node->vm_avl_right = noderightleft; noderight->vm_avl_left = node;
                noderight->vm_avl_height = 1 + (node->vm_avl_height = 1 + heightrightleft);
                *nodeplace = noderight;
            } else {
                noderight->vm_avl_left = noderightleft->vm_avl_right;
                node->vm_avl_right = noderightleft->vm_avl_left;
                noderightleft->vm_avl_right = noderight;
                noderightleft->vm_avl_left = node;
                noderight->vm_avl_height = node->vm_avl_height = heightrightleft;
                noderightleft->vm_avl_height = heightright;
                *nodeplace = noderightleft;
            }
        }
        else {
            int height = (heightleft<heightright ? heightright : heightleft) + 1;
            if (height == node->vm_avl_height)
                break;
            node->vm_avl_height = height;
        }
    }
}