示例#1
0
文件: hv.c 项目: julesy89/moo-java
static avl_node_t *
avl_insert_after(avl_tree_t *avltree, avl_node_t *node, avl_node_t *newnode) {
/*	if(!node)
		return avltree->head
			? avl_insert_before(avltree, avltree->head, newnode)
			: avl_insert_top(avltree, newnode);

	if(node->right)
		return avl_insert_before(avltree, node->next, newnode);
*/
        assert (node);
        assert (!node->right);

	avl_clear_node(newnode);

	newnode->prev = node;
	newnode->parent = node;

	newnode->next = node->next;
	if(node->next)
		node->next->prev = newnode;
	else
		avltree->tail = newnode;
	node->next = newnode;

	node->right = newnode;
	avl_rebalance(avltree, node);
	return newnode;
}
示例#2
0
/* Insert a node into a tree, and
 *  * return the node to the left of it and the node to the right of it.                                                       
 *   */
static void avl_insert_neighbours (struct vm_area_struct * new_node, struct vm_area_struct ** ptree,                        
        struct vm_area_struct ** to_the_left, struct vm_area_struct ** to_the_right)                                            
{   
    vm_avl_key_t key = new_node->vm_avl_key;
    struct vm_area_struct ** nodeplace = ptree;
    struct vm_area_struct ** stack[avl_maxheight];                                                                          
    int stack_count = 0;
    struct vm_area_struct *** stack_ptr = &stack[0]; /* = &stack[stackcount] */                                             
    *to_the_left = *to_the_right = NULL;                                                                                    
    for (;;) { 
        struct vm_area_struct * node = *nodeplace;                                                                          
        if (node == avl_empty)                                                                                              
            break;
        *stack_ptr++ = nodeplace; stack_count++;                                                                            
        if (key < node->vm_avl_key) {                                                                                       
            *to_the_right = node;
            nodeplace = &node->vm_avl_left;                                                                                 
        } else {
            *to_the_left = node;
            nodeplace = &node->vm_avl_right;                                                                                
        }                                                                                                                   
    }
    new_node->vm_avl_left = avl_empty;
    new_node->vm_avl_right = avl_empty;                                                                                     
    new_node->vm_avl_height = 1;                                                                                            
    *nodeplace = new_node;
    avl_rebalance(stack_ptr,stack_count);                                                                                   
}           
示例#3
0
static avl_node_t* avl_insert_node(
	bs_avl_t* avl, 
	avl_node_t *parent, 
	avl_data_t data)
{
	avl_node_t *new_node = NULL;

	if(NULL == avl || NULL == avl->compare)
	{
		return NULL;
	}

	if(NULL == parent)
	{
		new_node = (avl_node_t*)bs_malloc(sizeof(avl_node_t));
		if(NULL == new_node)
		{
			bs_debug("Failed to allocate memory!\n");
			return NULL;
		}
		new_node->left_child = NULL;
		new_node->right_child = NULL;
		new_node->data = data;
		//bs_debug("insert %d \n", (int8_t)data);
		return new_node;
	}
	else if(avl->compare(parent->data, data) < 0)
	{
		//bs_debug("parent->data[%c] < data[%c] \n", parent->data, data);
		parent->right_child = 
			avl_insert_node(avl, parent->right_child, data);
		return avl_rebalance(parent);
	}
	else if(avl->compare(parent->data, data) > 0)
	{
		//bs_debug("parent->data[%c] > data[%c] \n", parent->data, data);
		parent->left_child = 
			avl_insert_node(avl, parent->left_child, data);
		return avl_rebalance(parent);
	}
	else
	{
		//bs_debug("same data!! \n");
	}

	return parent;
}
示例#4
0
文件: hv.c 项目: julesy89/moo-java
/*
 * avl_unlink_node:
 * Removes the given node.  Does not delete the item at that node.
 * The item of the node may be freed before calling avl_unlink_node.
 * (In other words, it is not referenced by this function.)
 */
static void
avl_unlink_node(avl_tree_t *avltree, avl_node_t *avlnode) {
	avl_node_t *parent;
	avl_node_t **superparent;
	avl_node_t *subst, *left, *right;
	avl_node_t *balnode;

	if(avlnode->prev)
		avlnode->prev->next = avlnode->next;
	else
		avltree->head = avlnode->next;

	if(avlnode->next)
		avlnode->next->prev = avlnode->prev;
	else
		avltree->tail = avlnode->prev;

	parent = avlnode->parent;

	superparent = parent
		? avlnode == parent->left ? &parent->left : &parent->right
		: &avltree->top;

	left = avlnode->left;
	right = avlnode->right;
	if(!left) {
		*superparent = right;
		if(right)
			right->parent = parent;
		balnode = parent;
	} else if(!right) {
		*superparent = left;
		left->parent = parent;
		balnode = parent;
	} else {
		subst = avlnode->prev;
		if(subst == left) {
			balnode = subst;
		} else {
			balnode = subst->parent;
			balnode->right = subst->left;
			if(balnode->right)
				balnode->right->parent = balnode;
			subst->left = left;
			left->parent = subst;
		}
		subst->right = right;
		subst->parent = parent;
		right->parent = subst;
		*superparent = subst;
	}

	avl_rebalance(avltree, balnode);
}
示例#5
0
int32_t bs_avl_insert(bs_avl_t* avl, avl_data_t data)
{
	avl->root = (void*)avl_insert_node(avl, 
						(avl_node_t*)avl->root, data);
	avl->root = avl_rebalance((avl_node_t*)avl->root);
	//bs_debug("root:%p\n", avl->root);

	if(NULL == avl->root) 
		return -1;

	return 0;
}
示例#6
0
void avl_erase (avl_node_t *node, avl_node_t **tree)
{
  avl_node_t *parent = node->avl_parent;
  avl_node_t **arc_to_deleted;
  avl_node_t *newnode;
  avl_node_t *deepest;
	
  if (!parent)
    arc_to_deleted = tree;
  else if (parent->avl_left == node)
    arc_to_deleted = &parent->avl_left;
  else
    arc_to_deleted = &parent->avl_right;

  deepest = node;
  if (!node->avl_left) {
    /* The easy way -- just remove a level from the tree */
    newnode = node->avl_right;
    if (newnode)
      newnode->avl_parent = node->avl_parent;

  } else {
    /* The hard way -- the node we want is the rightmost child in
       the left subtree */

    avl_node_t **arc = &node->avl_left;
    for (;;) {
      newnode = *arc;
      if (!newnode->avl_right) break;
      deepest = newnode;
      arc = &newnode->avl_right;
    }

    /* The trees lose a level here */
    *arc = newnode->avl_left;

    /* Fix all the links to put the node in place */
    newnode->avl_parent = node->avl_parent;
    newnode->avl_left = node->avl_left;
    newnode->avl_right = node->avl_right;
    newnode->avl_height = node->avl_height;

    if (newnode->avl_left)
      newnode->avl_left->avl_parent = newnode;
    if (newnode->avl_right)
      newnode->avl_right->avl_parent = newnode;
  }

  *arc_to_deleted = newnode;
  avl_rebalance(deepest->avl_parent, tree);
}
示例#7
0
/* Removes a node out of a tree. */
static void avl_remove (struct vm_area_struct * node_to_delete, struct vm_area_struct ** ptree)                             
{   
    vm_avl_key_t key = node_to_delete->vm_avl_key;                                                                          
    struct vm_area_struct ** nodeplace = ptree;
    struct vm_area_struct ** stack[avl_maxheight];                                                                          
    int stack_count = 0;
    struct vm_area_struct *** stack_ptr = &stack[0]; /* = &stack[stackcount] */                                             
    struct vm_area_struct ** nodeplace_to_delete;                                                                           
    for (;;) { 
        struct vm_area_struct * node = *nodeplace;
        if (node == avl_empty) {
            /* what? node_to_delete not found in tree? */
            printk("avl_remove: node to delete not found in tree\n");
            return;
        }
        *stack_ptr++ = nodeplace; stack_count++;
        if (key == node->vm_avl_key)
            break;
        if (key < node->vm_avl_key)
            nodeplace = &node->vm_avl_left;
        else
            nodeplace = &node->vm_avl_right;
    }
    nodeplace_to_delete = nodeplace;
    /* Have to remove node_to_delete = *nodeplace_to_delete. */
    if (node_to_delete->vm_avl_left == avl_empty) {
        *nodeplace_to_delete = node_to_delete->vm_avl_right;
        stack_ptr--; stack_count--;
    } else {
        struct vm_area_struct *** stack_ptr_to_delete = stack_ptr;
        struct vm_area_struct ** nodeplace = &node_to_delete->vm_avl_left;
        struct vm_area_struct * node;
        for (;;) {
            node = *nodeplace;
            if (node->vm_avl_right == avl_empty)
                break;
            *stack_ptr++ = nodeplace; stack_count++;
            nodeplace = &node->vm_avl_right;
        }
        *nodeplace = node->vm_avl_left;
        /* node replaces node_to_delete */
        node->vm_avl_left = node_to_delete->vm_avl_left;
        node->vm_avl_right = node_to_delete->vm_avl_right;
        node->vm_avl_height = node_to_delete->vm_avl_height;
        *nodeplace_to_delete = node; /* replace node_to_delete */
        *stack_ptr_to_delete = &node->vm_avl_left; /* replace &node_to_delete->vm_avl_left */
    }
    avl_rebalance(stack_ptr,stack_count);
}
示例#8
0
static void avl_insert (struct vm_area_struct * new_node, struct vm_area_struct ** ptree)
{
    vm_avl_key_t key = new_node->vm_avl_key;
    struct vm_area_struct ** nodeplace = ptree;
    struct vm_area_struct ** stack[avl_maxheight];
    int stack_count = 0;
    struct vm_area_struct *** stack_ptr = &stack[0]; /* = &stack[stackcount] */
    for (;;) {
        struct vm_area_struct * node = *nodeplace;
        if (node == avl_empty)
            break;
        *stack_ptr++ = nodeplace; stack_count++;
        if (key < node->vm_avl_key)
            nodeplace = &node->vm_avl_left;
        else
            nodeplace = &node->vm_avl_right;
    }   
    new_node->vm_avl_left = avl_empty;
    new_node->vm_avl_right = avl_empty;
    new_node->vm_avl_height = 1;
    *nodeplace = new_node;
    avl_rebalance(stack_ptr,stack_count);
}
示例#9
0
void avl_delete(sb_avl * instance, avl_node * p)
{
	/** Case 1: p has no children **/
	if (p->left == NULL && p->right == NULL) {
		/** Case 1a: p is the root **/
		if (p == avl_root(instance)) {
			free(avl_root(instance));
			return;
		}
		
		avl_node * parent = p->parent;

		if (parent->left == p) {
			parent->left = NULL;
		}
		else {
			parent->right = NULL;
		}

		avl_recomp_height(parent);

		avl_rebalance(instance, parent);

		free(p);

		return;
	}

	/** Case 2: p has 1 child **/
	if (p->right == NULL) {

		/** Case 2a: p is the root **/
		if (p == avl_root(instance)) {

			// update the new root's parent
			instance->root->left->parent = NULL;

			// change the root to the new root
			instance->root = instance->root->left;

			// free the old root
			free(p);

			// re-compute heights
			avl_recomp_height(instance->root);

			// and re-balance
			avl_rebalance(instance, instance->root);
			return;
		}

		avl_node * parent = p->parent;

		if (parent->left == p) {
			parent->left = p->left;
			p->left->parent = parent;
		}
		else {
			parent->right = p->left;
			p->left->parent = parent;
		}

		free(p);

		avl_recomp_height(parent);

		avl_rebalance(instance, parent);

		return;
	}

	if (p->left == NULL) {
		if ( p == avl_root(instance) ) {
			// update the new root's parent
			instance->root->right->parent = NULL;

			// change the root
			instance->root = instance->root->right;

			// free the old root
			free(p);

			// re-compute heights
			avl_recomp_height(instance->root);

			// and re-balance
			avl_rebalance(instance, instance->root);

			return;
		}

		avl_node * parent = p->parent;

		if (parent->left == p) {
			parent->left = p->right;
			p->right->parent = parent;
		}
		else {
			parent->right = p->right;
			p->right->parent = parent;
		}

		free(p);

		avl_recomp_height(parent);

		avl_rebalance(instance, parent);

		return;
	}

	/** Case 3: p has 2 children **/
	if ( p->right->left == NULL ) {

		// overwrite p with p->right.
		// This leaves p->right with no way to
		// get to it. So remove p->right.
		avl_node * tmp = p->right;
		p->key = p->right->key;
		p->value = p->right->value;
		p->right = p->right->right;

		free(tmp);

		avl_recomp_height(p->parent);

		avl_rebalance(instance, p->parent);

		return;
	}

	avl_node * succ = p->right;
	avl_node * succParent;

	while ( succ->left != NULL ) {
		succ = succ->left;
	}

	p->key = succ->key;
	p->value = succ->value;

	succParent = succ->parent;
	succParent->left = succ->right;

	free(succ);

	avl_recomp_height(succParent);
	
	avl_rebalance(instance, succParent);

	return;
}
示例#10
0
static avl_node_t* avl_remove_node(
	bs_avl_t* avl, 
	avl_node_t *parent, 
	avl_data_t data)
{
	avl_node_t* toRemove = NULL;
	avl_node_t* next = NULL;
	if(NULL == avl || NULL == avl->compare)
		return NULL;

	if(NULL == parent)
	{
		bs_debug("not found! \n");
		return NULL;
	}

	if(avl->compare(parent->data, data) < 0)
	{
		parent->right_child = avl_remove_node(avl, parent->right_child, data);
		return avl_rebalance(parent);
	}
	else if(avl->compare(parent->data, data) > 0)
	{
		parent->left_child = avl_remove_node(avl, parent->left_child, data);
		return avl_rebalance(parent);
	}
	else
	{
		bs_debug("remove :%d \n", parent->data);
		if(!parent->left_child && !parent->right_child)
		{
			bs_free((void*)parent);
			parent = NULL;
		}
		else if(!parent->left_child)
		{
			toRemove = parent;
			parent = parent->right_child;
			bs_free((void*)toRemove);

		}
		else if(!parent->right_child)
		{
			toRemove = parent;
			parent = parent->left_child;
			bs_free((void*)toRemove);
		}
		else
		{
			toRemove = parent;
			next = toRemove->right_child;
			if(next->left_child == NULL)
			{
				parent = next;
				parent->left_child = toRemove->left_child;
			}
			else
			{
				while(next->left_child->left_child)
					next = next->left_child;
				parent = next->left_child;
				next->left_child = parent->right_child;
				
				parent->left_child = toRemove->left_child;
				parent->right_child = toRemove->right_child;
			}

			bs_free(toRemove);
		}

		return avl_rebalance(parent);
	}
}