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; }
/* 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); }
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; }
/* * 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); }
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; }
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); }
/* 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); }
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); }
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; }
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); } }