// tree_delete_balance has 2 more case than tree_insert_balance. // these are: a: node->balance > 0, b: node->right-balance = 0; // the other case is sysmetrical to this case. static void tree_delete_balance(avl_node* node) { if(node->balance > 0) { avl_node *child = node->right; if(child->balance == 0) { node->balance = 1; child->balance = -1; left_rotation(node); } else tree_insert_balance(node); } else if(node->balance < 0) { avl_node *child = node->left; if(child->balance == 0) { node->balance = 1; child->balance = -1; right_rotation(node); } else tree_insert_balance(node); } }
static void right_left_rotation(avl_node *node) { avl_node *right_node = node->right; right_rotation(right_node); left_rotation(node); }
static void left_right_rotation(avl_node *node) { avl_node *left_node = node->left; left_rotation(left_node); right_rotation(node); }
/* * if the balance of the node is greater than 1 or less than -1, * then balance the tree. * case 1. a: node->balance >= 2, b: node->right->balance > 0; * left_rotation the node. a->balance = b->balance. * case 2. a: node->balance >=2, b: node->right->balance < 0, c: node->right->left->balance ==0; * right_left_rotation the node. a->balance = b->balance = c->balance = 0. * case 3. a: node->balance >= 2, b: node->right->balance < 0, c: node->right->left->balance > 0; * right_left_roation the node. a->balance = -1, b->balance = 0, c->balance = 0; * case 4. a: node->balance >= 2, b: node->right->balance < 0, c: node->right->left->balance < 0; * right_left_rotation the node. a->balance = 0, b->balance = 1, c->balance = 0; * case 5 - 8 is symmetrical to case 1-4. */ static void tree_insert_balance(avl_node *node) { if(node->balance > 0) { avl_node *child = node->right; if(child->balance > 0) { node->balance = child->balance = 0; left_rotation(node); } else { avl_node *left_child = child->left; if(left_child->balance == 0) node->balance = child->balance = 0; else if(left_child->balance > 0) { node->balance = -1; child->balance = 0; } else { node->balance = 0; child->balance = 1; } left_child->balance = 0; right_left_rotation(node); } } else { avl_node *child = node->left; if(child->balance < 0) { node->balance = child->balance = 0; right_rotation(node); } else { avl_node *right_child= child->right; if(right_child->balance == 0) { node->balance = child->balance = 0; } else if(right_child->balance > 0) { node->balance = 0; child->balance = -1; } else { node->balance = 1; child->balance = 0; } right_child->balance = 0; left_right_rotation(node); } } }
void splay(const K& k, node_type*& n) { node_type* leftTreeMax; node_type* rightTreeMin; node_type header; header.left = header.right = null_node; leftTreeMax = rightTreeMin = &header; null_node->key = k; // guarantee a match for (;;) { if (comp(k, n->key)) { if (comp(k, n->left->key)) left_rotation(n); if (is_null(n->left)) break; // link right rightTreeMin->left = n; rightTreeMin = n; n = n->left; } else if (comp(n->key, k)) { if (comp(n->right->key, k)) right_rotation(n); if (is_null(n->right)) break; // link left leftTreeMax->right = n; leftTreeMax = n; n = n->right; } else { break; } } leftTreeMax->right = n->left; rightTreeMin->left = n->right; n->left = header.right; n->right = header.left; }
char * delete_line(text_t *txt, int index) { char *deleted_object; text_t *path_stack[100]; int path_st_p = 0; text_t *tmp_node, *upper_node, *other_node; tmp_node = txt; while (index != 1 || tmp_node->weight != 1) { path_stack[path_st_p++] = tmp_node; upper_node = tmp_node; if (index <= tmp_node->left->weight) { //printf("goes to the left <----\n"); tmp_node = tmp_node->left; tmp_node = upper_node->left; other_node = upper_node->right; } else { //printf("goes to the right---->\n"); index = index - tmp_node->left->weight; tmp_node = tmp_node->right; tmp_node = upper_node->right; other_node = upper_node->left; } } upper_node->key = other_node->key; upper_node->left = other_node->left; upper_node->right = other_node->right; upper_node->weight = other_node->weight; deleted_object = (char *) tmp_node->left; return_node(tmp_node); return_node(other_node); /*start rebalance*/ path_st_p -= 1; while (path_st_p > 0) { tmp_node = path_stack[--path_st_p]; tmp_node->weight = tmp_node->left->weight + tmp_node->right->weight; if (tmp_node->right->weight < ALPHA * tmp_node->weight) { if (tmp_node->left->left->weight > (ALPHA + EPSILON) * tmp_node->weight) { right_rotation(tmp_node); tmp_node->right->weight = tmp_node->right->left->weight + tmp_node->right->right->weight; } else { left_rotation(tmp_node->left); right_rotation(tmp_node); tmp_node->right->weight = tmp_node->right->left->weight + tmp_node->right->right->weight; tmp_node->left->weight = tmp_node->left->left->weight + tmp_node->left->right->weight; } } else if (tmp_node->left->weight < ALPHA * tmp_node->weight) { if (tmp_node->right->right->weight > (ALPHA + EPSILON) * tmp_node->weight) { left_rotation(tmp_node); tmp_node->left->weight = tmp_node->left->left->weight + tmp_node->left->right->weight; } else { right_rotation(tmp_node->right); left_rotation(tmp_node); tmp_node->right->weight = tmp_node->right->left->weight + tmp_node->right->right->weight; tmp_node->left->weight = tmp_node->left->left->weight + tmp_node->left->right->weight; } } } /*end rebalance*/ return (deleted_object); }
/* This function deletes the line of number index, renumbering all lines after that line, and returns a pointer to the deleted line */ char * delete_line(text_t *txt, int index) { text_t *tmp_node, *upper_node, *other_node; object_t *deleted_object; int count = index; int finished; tmp_node = txt; if (txt->left == NULL || length_text(txt) < index) { return NULL; } else if (txt->right == NULL) { deleted_object = (object_t *)txt->left; txt->left = NULL; txt->parent = NULL; txt->key = -1; txt->height = -1; return (deleted_object); } else { while(tmp_node->right != NULL) { upper_node = tmp_node; (tmp_node->key)--; if (count <= tmp_node->left->key) { tmp_node = tmp_node->left; tmp_node = upper_node->left; other_node = upper_node->right; } else { count -= tmp_node->left->key; tmp_node = tmp_node->right; tmp_node = upper_node->right; other_node = upper_node->left; } } upper_node->key = other_node->key; upper_node->left = other_node->left; upper_node->right = other_node->right; upper_node->height = other_node->height; if (upper_node->right != NULL) { upper_node->left->parent = upper_node; upper_node->right->parent = upper_node; } deleted_object = (object_t *) tmp_node->left; return_node(tmp_node); return_node(other_node); upper_node = upper_node->parent; tmp_node = upper_node; finished = 0; while(!finished && tmp_node!=NULL) { int tmp_height, old_height; old_height = tmp_node->height; if (tmp_node->left->height - tmp_node->right->height == 2) { if (tmp_node->left->left->height - tmp_node->right->height == 1) { right_rotation(tmp_node); tmp_node->right->height = tmp_node->right->left->height + 1; tmp_node->height = tmp_node->right->height + 1; tmp_node->right->key = tmp_node->right->left->key + tmp_node->right->right->key; tmp_node->key = tmp_node->left->key + tmp_node->right->key; } else { left_rotation(tmp_node->left); right_rotation(tmp_node); tmp_height = tmp_node->left->left->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; tmp_node->left->key = tmp_node->left->left->key + tmp_node->left->right->key; tmp_node->right->key = tmp_node->right->left->key + tmp_node->right->right->key; tmp_node->key = tmp_node->left->key + tmp_node->right->key; } } else if (tmp_node->left->height - tmp_node->right->height == -2) { if( tmp_node->right->right->height - tmp_node->left->height == 1) { left_rotation(tmp_node); tmp_node->left->height = tmp_node->left->right->height + 1; tmp_node->height = tmp_node->left->height + 1; tmp_node->left->key = tmp_node->left->left->key + tmp_node->left->right->key; tmp_node->key = tmp_node->left->key + tmp_node->right->key; } else { right_rotation(tmp_node->right); left_rotation(tmp_node); tmp_height = tmp_node->right->right->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; tmp_node->right->key = tmp_node->right->left->key + tmp_node->right->right->key; tmp_node->left->key = tmp_node->left->left->key + tmp_node->left->right->key; tmp_node->key = tmp_node->left->key + tmp_node->right->key; } } else { if(tmp_node->left->height > tmp_node->right->height) { tmp_node->height = tmp_node->left->height + 1; } else { tmp_node->height = tmp_node->right->height + 1; } } if (tmp_node->height == old_height) { finished = 1; } tmp_node = tmp_node->parent; } return (deleted_object); } }
/* This function appends new line as new last line */ void append_line(text_t *txt, char *new_line) { text_t *tmp_node = txt; int finished; if (txt->left == NULL) { txt->left = (text_t *) create_object(new_line); txt->right = NULL; txt->parent = NULL; txt->key = 1; txt->height = 0; } else { while(tmp_node->right != NULL) { (tmp_node->key)++; tmp_node = tmp_node->right; } text_t *old_leaf, *new_leaf; old_leaf = get_node(); new_leaf = get_node(); old_leaf->left = tmp_node->left; old_leaf->key = tmp_node->key; old_leaf->right = NULL; old_leaf->parent = tmp_node; old_leaf->height = 0; new_leaf->left = (text_t *) create_object(new_line); new_leaf->key = tmp_node->key; new_leaf->right = NULL; new_leaf->parent = tmp_node; new_leaf->height = 0; tmp_node->left = old_leaf; tmp_node->right = new_leaf; (tmp_node->key)++; tmp_node->height = 0; finished = 0; while(!finished && tmp_node!=NULL) { int tmp_height, old_height; old_height = tmp_node->height; if (tmp_node->left->height - tmp_node->right->height == 2) { if (tmp_node->left->left->height - tmp_node->right->height == 1) { right_rotation(tmp_node); tmp_node->right->height = tmp_node->right->left->height + 1; tmp_node->height = tmp_node->right->height + 1; tmp_node->right->key = tmp_node->right->left->key + tmp_node->right->right->key; tmp_node->key = tmp_node->left->key + tmp_node->right->key; } else { left_rotation(tmp_node->left); right_rotation(tmp_node); tmp_height = tmp_node->left->left->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; tmp_node->left->key = tmp_node->left->left->key + tmp_node->left->right->key; tmp_node->right->key = tmp_node->right->left->key + tmp_node->right->right->key; tmp_node->key = tmp_node->left->key + tmp_node->right->key; } } else if (tmp_node->left->height - tmp_node->right->height == -2) { if( tmp_node->right->right->height - tmp_node->left->height == 1) { left_rotation(tmp_node); tmp_node->left->height = tmp_node->left->right->height + 1; tmp_node->height = tmp_node->left->height + 1; tmp_node->left->key = tmp_node->left->left->key + tmp_node->left->right->key; tmp_node->key = tmp_node->left->key + tmp_node->right->key; } else { right_rotation(tmp_node->right); left_rotation(tmp_node); tmp_height = tmp_node->right->right->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; tmp_node->right->key = tmp_node->right->left->key + tmp_node->right->right->key; tmp_node->left->key = tmp_node->left->left->key + tmp_node->left->right->key; tmp_node->key = tmp_node->left->key + tmp_node->right->key; } } else { if(tmp_node->left->height > tmp_node->right->height) { tmp_node->height = tmp_node->left->height + 1; } else { tmp_node->height = tmp_node->right->height + 1; } } if (tmp_node->height == old_height) { finished = 1; } tmp_node = tmp_node->parent; } } }
char *delete_line(text_t *txt, int index) { text_t *tmp_node, *upper_node, *other_node; object_t *deleted_object; int finished; text_t * path_stack[100]; int path_st_p; int tmp_height, old_height; if(txt == NULL) { return NULL; } if(index > txt->key) { return NULL; } if(txt->right == NULL) { if(txt->key == index){ deleted_object = (object_t *)txt->left; txt->left = NULL; txt->key = 0; return (deleted_object); } }else{ path_st_p = 0; tmp_node = txt; while(tmp_node->right != NULL){ path_stack[path_st_p++] = tmp_node; upper_node = tmp_node; if(tmp_node->left->key >= index) { tmp_node = tmp_node->left; other_node = upper_node->right; }else { index -= tmp_node->left->key; tmp_node = tmp_node->right; other_node = upper_node->left; } } { upper_node->key = other_node->key; upper_node->left = other_node->left; upper_node->right = other_node->right; upper_node->height = other_node->height; deleted_object = (object_t *) tmp_node->left; return_node(tmp_node); return_node(other_node); } //rebalance finished = 0; path_st_p -= 1; while(path_st_p > 0 && !finished){ tmp_node = path_stack[--path_st_p]; tmp_node->key = tmp_node->left->key + tmp_node->right->key; old_height = tmp_node->height; if(tmp_node->left->height - tmp_node->right->height == 2 ){ if(tmp_node->left->left->height - tmp_node->right->height == 1 ){ right_rotation(tmp_node); tmp_node->key = tmp_node->right->key; tmp_node->right->key = tmp_node->right->left->key + tmp_node->right->right->key; tmp_node->right->height = tmp_node->right->left->height + 1; tmp_node->height = tmp_node->right->height + 1; }else{ left_rotation(tmp_node->left); right_rotation(tmp_node); tmp_node->key = tmp_node->right->key; tmp_node->right->key = tmp_node->right->left->key + tmp_node->right->right->key; tmp_height = tmp_node->left->left->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } }else if (tmp_node->left->height - tmp_node->right->height == -2 ){ if( tmp_node->right->right->height - tmp_node->left->height == 1 ){ left_rotation(tmp_node); //add line to update key. tmp_node->key = tmp_node->left->key; tmp_node->left->key = tmp_node->left->left->key + tmp_node->left->right->key; tmp_node->left->height = tmp_node->left->right->height + 1; tmp_node->height = tmp_node->left->height + 1; }else{ right_rotation(tmp_node->right); left_rotation(tmp_node); tmp_node->key = tmp_node->left->key; tmp_node->left->key = tmp_node->left->left->key + tmp_node->left->right->key; tmp_height = tmp_node->right->right->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } }else{ if(tmp_node->left->height > tmp_node->right->height) tmp_node->height = tmp_node->left->height + 1; else tmp_node->height = tmp_node->right->height + 1; } if(tmp_node->height == old_height) finished = 1; } while( path_st_p > 0){ tmp_node = path_stack[--path_st_p]; // add new line update key tmp_node->key = tmp_node->left->key + tmp_node->right->key; } return (deleted_object); } return NULL; }
void insert_line(text_t *txt, int index, char * new_line) { text_t *tmp_node; int finished; text_t * path_stack[100]; int path_st_p; text_t *old_leaf, *new_leaf; int tmp_height, old_height; if( txt->left == NULL ){ txt->left = (text_t *)new_line; txt->key = 1; txt->height = 0; txt->right = NULL; return; }else{ path_st_p = 0; tmp_node = txt; //append or not if(index > txt->key) { append_line(txt, new_line); return; } while( tmp_node->right != NULL ){ path_stack[path_st_p++] = tmp_node; if(tmp_node->left->key >= index) { tmp_node = tmp_node->left; }else { index -= tmp_node->left->key; tmp_node = tmp_node->right; } } { old_leaf = get_node(); old_leaf->left = tmp_node->left; old_leaf->key = tmp_node->key; old_leaf->right = NULL; old_leaf->height = 0; new_leaf = get_node(); new_leaf->left = (text_t *)new_line; new_leaf->key = 1; new_leaf->right = NULL; new_leaf->height = 0; tmp_node->left = new_leaf; tmp_node->right = old_leaf; tmp_node->key = old_leaf->key + new_leaf->key; tmp_node->height = 1; } //rebalance */ finished = 0; while( path_st_p > 0 && !finished ){ tmp_node = path_stack[--path_st_p]; //update key here; tmp_node->key = tmp_node->left->key + tmp_node->right->key; old_height = tmp_node->height; if( tmp_node->left->height - tmp_node->right->height == 2 ){ if( tmp_node->left->left->height - tmp_node->right->height == 1 ){ right_rotation( tmp_node ); tmp_node->right->height = tmp_node->right->left->height + 1; tmp_node->height = tmp_node->right->height + 1; // update key tmp_node->key = tmp_node->right->key; tmp_node->right->key = tmp_node->right->left->key + tmp_node->right->right->key; }else{ // need change here !!!!!! or not left_rotation( tmp_node->left ); int switch_tmp = tmp_node->left->key; tmp_node->left->key = tmp_node->left->left->key; tmp_node->left->left->key = switch_tmp; right_rotation( tmp_node ); tmp_node->key = tmp_node->right->key; tmp_node->right->key = tmp_node->right->left->key + tmp_node->right->right->key; tmp_height = tmp_node->left->left->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } }else if ( tmp_node->left->height - tmp_node->right->height == -2 ){ if( tmp_node->right->right->height - tmp_node->left->height == 1 ){ left_rotation( tmp_node ); tmp_node->left->height = tmp_node->left->right->height + 1; tmp_node->height = tmp_node->left->height + 1; //add line to update key. tmp_node->key = tmp_node->left->key; tmp_node->left->key = tmp_node->left->left->key + tmp_node->left->right->key; }else{ right_rotation( tmp_node->right ); int switch_tmp = tmp_node->right->key; tmp_node->right->key = tmp_node->right->right->key; tmp_node->right->right->key = switch_tmp; left_rotation( tmp_node ); tmp_node->key = tmp_node->left->key; tmp_node->left->key = tmp_node->left->left->key + tmp_node->left->right->key; tmp_height = tmp_node->right->right->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } }else{ if( tmp_node->left->height > tmp_node->right->height ) tmp_node->height = tmp_node->left->height + 1; else tmp_node->height = tmp_node->right->height + 1; } if( tmp_node->height == old_height ) finished = 1; } while( path_st_p > 0){ tmp_node = path_stack[--path_st_p]; // add new line update key tmp_node->key = tmp_node->left->key + tmp_node->right->key; } } }
int insert (tree_node_t * tree, key_t new_key, object_t * new_object) { tree_node_t *tmp_node; int finished; if (tree->left == NULL) { tree->left = (tree_node_t *) new_object; tree->key = new_key; tree->height = 0; tree->right = NULL; } else { tree_node_t *path_stack[100]; int path_st_p = 0; tmp_node = tree; while (tmp_node->right != NULL) { path_stack[path_st_p++] = tmp_node; if (new_key < tmp_node->key) tmp_node = tmp_node->left; else tmp_node = tmp_node->right; } /* found the candidate leaf. Test whether key distinct */ if (tmp_node->key == new_key) return (-1); /* key is distinct, now perform the insert */ { tree_node_t *old_leaf, *new_leaf; old_leaf = get_node (); old_leaf->left = tmp_node->left; old_leaf->key = tmp_node->key; old_leaf->right = NULL; old_leaf->height = 0; new_leaf = get_node (); new_leaf->left = (tree_node_t *) new_object; new_leaf->key = new_key; new_leaf->right = NULL; new_leaf->height = 0; if (tmp_node->key < new_key) { tmp_node->left = old_leaf; tmp_node->right = new_leaf; tmp_node->key = new_key; } else { tmp_node->left = new_leaf; tmp_node->right = old_leaf; } tmp_node->height = 1; } /* rebalance */ finished = 0; while (path_st_p > 0 && !finished) { int tmp_height, old_height; tmp_node = path_stack[--path_st_p]; old_height = tmp_node->height; if (tmp_node->left->height - tmp_node->right->height == 2) { if (tmp_node->left->left->height - tmp_node->right->height == 1) { right_rotation (tmp_node); tmp_node->right->height = tmp_node->right->left->height + 1; tmp_node->height = tmp_node->right->height + 1; } else { left_rotation (tmp_node->left); right_rotation (tmp_node); tmp_height = tmp_node->left->left->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } } else if (tmp_node->left->height - tmp_node->right->height == -2) { if (tmp_node->right->right->height - tmp_node->left->height == 1) { left_rotation (tmp_node); tmp_node->left->height = tmp_node->left->right->height + 1; tmp_node->height = tmp_node->left->height + 1; } else { right_rotation (tmp_node->right); left_rotation (tmp_node); tmp_height = tmp_node->right->right->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } } else /* update height even if there was no rotation */ { if (tmp_node->left->height > tmp_node->right->height) tmp_node->height = tmp_node->left->height + 1; else tmp_node->height = tmp_node->right->height + 1; } if (tmp_node->height == old_height) finished = 1; } } return (0); }
char * delete_line(tree_node *tree, int delete_key){ //Deletes the line of the number `delete_key`, renumbering all lines //after that line, and returns a pointer to the deleted line. tree_node *temp_node, *upper_node, *other_node; char *deleted_object; int finished; if (tree->left == NULL){ //empty tree return NULL; } else{ //both side of the tree isn't empty. tree_node *stack[STACK_MAX]; int stack_ptr = 0; temp_node = tree; while (temp_node->right != NULL){ stack[stack_ptr++] = temp_node; upper_node = temp_node; if (delete_key <= temp_node->left->key){ temp_node = temp_node->left; other_node = upper_node->right; } else{ delete_key -= temp_node->left->key; other_node = upper_node->left; temp_node = temp_node->right; } } tree_node *temp; //temp_node = stack[--stack_ptr]; temp = stack[--stack_ptr]; if (delete_key == 1){ //perform deletion upper_node->left = other_node->left; upper_node->right = other_node->right; upper_node->height = other_node->height; upper_node->key = other_node->key; deleted_object = (char *) temp_node->left; int tempsize = stack_ptr; while (stack_ptr > 0){ temp = stack[--stack_ptr]; temp->key -= 1; } //rebalancing tree finished = 0; stack_ptr = tempsize; //stack_ptr -= 1; while(stack_ptr>0 && !finished){ int temp_height, old_height; temp_node = stack[--stack_ptr]; old_height = temp_node->height; if(temp_node->left->height - temp_node->right->height == 2){ if (temp_node->left->left->height - temp_node->right->height == 1){ right_rotation(temp_node); temp_node->right->height = temp_node->right->left->height + 1; temp_node->height = temp_node->right->height + 1; } else{ left_rotation(temp_node->left); right_rotation(temp_node); temp_height = temp_node->left->left->height; temp_node->left->height = temp_height + 1; temp_node->right->height = temp_height + 1; temp_node->height = temp_height + 2; } } else if (temp_node->left->height - temp_node->right->height == -2){ if (temp_node->right->right->height - temp_node->left->height == 1){ left_rotation(temp_node); temp_node->left->height = temp_node->left->right->height + 1; temp_node->height = temp_node->left->height + 1; } else{ right_rotation(temp_node->right); left_rotation(temp_node); temp_height = temp_node->right->right->height; temp_node->left->height = temp_height + 1; temp_node->right->height = temp_height + 1; temp_node->height = temp_height + 2; } } else{ if (temp_node->left->height > temp_node->right->height){ temp_node->height = temp_node->left->height + 1; } else{ temp_node->height = temp_node->right->height + 1; } } if (old_height == temp_height){ finished = 1; } } return deleted_object; } else{ return NULL; } } }
object_t *_delete_balanced(tree_node_t *tree, key_t delete_key) { tree_node_t *tmp_node, *upper_node, *other_node; //int finished; stack_t *stack; object_t *deleted_object; if( tree->left == NULL ) return( NULL ); else if( tree->right == NULL ) { if( tree->key == delete_key ) { deleted_object = (object_t *) tree->left; tree->left = NULL; return( deleted_object ); } else return( NULL ); } else { stack = create_stack(); tmp_node = tree; while( tmp_node->right != NULL ) { push(tmp_node,stack); upper_node = tmp_node; if( delete_key <= tmp_node->left->key ) { tmp_node = upper_node->left; other_node = upper_node->right; } else { delete_key = delete_key - tmp_node->left->key; tmp_node = upper_node->right; other_node = upper_node->left; } } if( tmp_node->key != delete_key ) return( NULL ); else { upper_node->key = other_node->key; upper_node->left = other_node->left; upper_node->right = other_node->right; upper_node->height = 0; deleted_object = (object_t *) tmp_node->left; return_node( tmp_node ); return_node( other_node ); update_leafcount(upper_node); } /* rebalance */ //finished = 0; /*if (!stack_empty(stack)) { print_stack(stack); }*/ //Throw out the top of stack. pop(stack); while( !stack_empty(stack))// && !finished ) { int tmp_height, old_height; tmp_node = pop(stack); tmp_node->key = tmp_node->left->key + tmp_node->right->key; old_height= tmp_node->height; if( tmp_node->left->height - tmp_node->right->height == 2 ) { if( tmp_node->left->left->height - tmp_node->right->height == 1 ) { right_rotation(tmp_node); tmp_node->right->height = tmp_node->right->left->height + 1; tmp_node->height = tmp_node->right->height + 1; } else { left_rotation(tmp_node->left); right_rotation(tmp_node); tmp_height = tmp_node->left->left->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } } else if( tmp_node->left->height - tmp_node->right->height == -2 ) { if( tmp_node->right->right->height - tmp_node->left->height == 1 ) { left_rotation( tmp_node ); tmp_node->left->height = tmp_node->left->right->height + 1; tmp_node->height = tmp_node->left->height + 1; } else { right_rotation( tmp_node->right ); left_rotation( tmp_node ); tmp_height = tmp_node->right->right->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } } else /* update height even if there was no rotation */ { if( tmp_node->left->height > tmp_node->right->height ) tmp_node->height = tmp_node->left->height + 1; else tmp_node->height = tmp_node->right->height + 1; } update_leafcount(tmp_node); /*if( tmp_node->height == old_height ) finished = 1;*/ } remove_stack(stack); } return( deleted_object ); }
int insert_balanced(tree_node_t *tree, key_t new_key,object_t *new_object) { tree_node_t *tmp_node; //int finished; stack_t *stack; int inserted_key = 32767; tree_node_t *last_node; if( tree->left == NULL ) { tree->left = (tree_node_t *) new_object; tree->key = new_key; tree->height = 0; tree->left_leaves = tree->right_leaves = 0; tree->right = NULL; } else { stack = create_stack(); tmp_node = tree; last_node = tmp_node; while( tmp_node->right != NULL ) { push(tmp_node,stack); last_node = tmp_node; if( new_key <= tmp_node->left->key ) tmp_node = tmp_node->left; else { new_key = new_key - tmp_node->left->key; tmp_node = tmp_node->right; } } /* found the candidate leaf. Test whether key distinct */ if( tmp_node->key == new_key ) { tree_node_t *old_leaf, *new_leaf; old_leaf = get_node(); old_leaf->left = tmp_node->left; old_leaf->key = tmp_node->key; old_leaf->right= NULL; old_leaf->height = 0; new_leaf = get_node(); new_leaf->left = (tree_node_t *) new_object; new_leaf->key = 1; new_leaf->right = NULL; new_leaf->height = 0; tmp_node->left = new_leaf; tmp_node->right = old_leaf; tmp_node->height = 1; tmp_node->key = new_leaf->key + old_leaf->key; } else { tree_node_t *old_leaf, *new_leaf; old_leaf = get_node(); old_leaf->left = tmp_node->left; old_leaf->key = tmp_node->key; old_leaf->right= NULL; old_leaf->height = 0; new_leaf = get_node(); new_leaf->left = (tree_node_t *) new_object; new_leaf->key = 1; new_leaf->right = NULL; new_leaf->height = 0; tmp_node->left = old_leaf; tmp_node->right = new_leaf; tmp_node->key = new_leaf->key + old_leaf->key; tmp_node->height = 1; } /* rebalance */ while( !stack_empty(stack))// && !finished ) { int tmp_height, old_height; tmp_node = pop(stack); tmp_node->key = tmp_node->left->key + tmp_node->right->key; old_height= tmp_node->height; if( tmp_node->left->height - tmp_node->right->height == 2 ) { if( tmp_node->left->left->height - tmp_node->right->height == 1 ) { right_rotation( tmp_node ); tmp_node->right->height = tmp_node->right->left->height + 1; tmp_node->height = tmp_node->right->height + 1; } else { left_rotation(tmp_node->left); right_rotation( tmp_node ); tmp_height = tmp_node->left->left->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } } else if( tmp_node->left->height - tmp_node->right->height == -2 ) { if( tmp_node->right->right->height - tmp_node->left->height == 1 ) { left_rotation( tmp_node ); tmp_node->left->height = tmp_node->left->right->height + 1; tmp_node->height = tmp_node->left->height + 1; } else { right_rotation( tmp_node->right ); left_rotation( tmp_node ); tmp_height = tmp_node->right->right->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } } else /* update height even if there was no rotation */ { if( tmp_node->left->height > tmp_node->right->height ) { tmp_node->height = tmp_node->left->height + 1; } else { tmp_node->height = tmp_node->right->height + 1; } } } remove_stack(stack); } return( 0 ); }
void insert_line(text_t *tree, int index, char *new_line) { text_t *tmp_node; text_t * path_stack[100]; int path_st_p = 0; int intial_index=index; tmp_node = tree; // stores only the root node. while (index!=1 || tmp_node->weight!=1) { path_stack[path_st_p++] = tmp_node; if (index <= tmp_node->left->weight) { //printf("goes to the left <----\n"); tmp_node=tmp_node->left; } else { //printf("goes to the right---->\n"); index= index - tmp_node->left->weight; tmp_node=tmp_node->right; } } text_t *old_leaf, *new_leaf; old_leaf = get_node(); old_leaf->left = tmp_node->left; old_leaf->key = tmp_node->key; old_leaf->right = NULL; old_leaf->weight = 1; new_leaf = get_node(); new_leaf->left = (text_t *) new_line; new_leaf->key = intial_index; new_leaf->right = NULL; new_leaf->weight = 1; tmp_node->left = new_leaf; tmp_node->right = old_leaf; tmp_node->key=intial_index+1; tmp_node->right->key=intial_index+1; tmp_node->weight = 2; /* rebalance */ while (path_st_p > 0) { tmp_node = path_stack[--path_st_p]; tmp_node->weight = tmp_node->left->weight + tmp_node->right->weight; if (tmp_node->right->weight < ALPHA * tmp_node->weight) { if (tmp_node->left->left->weight > (ALPHA + EPSILON) * tmp_node->weight) { right_rotation(tmp_node); tmp_node->right->weight = tmp_node->right->left->weight + tmp_node->right->right->weight; } else { left_rotation(tmp_node->left); right_rotation(tmp_node); tmp_node->right->weight = tmp_node->right->left->weight + tmp_node->right->right->weight; tmp_node->left->weight = tmp_node->left->left->weight + tmp_node->left->right->weight; } } else if (tmp_node->left->weight < ALPHA * tmp_node->weight) { if (tmp_node->right->right->weight > (ALPHA + EPSILON) * tmp_node->weight) { left_rotation(tmp_node); tmp_node->left->weight = tmp_node->left->left->weight + tmp_node->left->right->weight; } else { right_rotation(tmp_node->right); left_rotation(tmp_node); tmp_node->right->weight = tmp_node->right->left->weight + tmp_node->right->right->weight; tmp_node->left->weight = tmp_node->left->left->weight + tmp_node->left->right->weight; } } } }
/* Deletes the line of number index, renumbering all lines after that line, and returns a pointer to the deleted line */ char * delete_line(text_t *txt, int index){ text_t * init_text=txt; if(txt==NULL){ //No Tree return NULL; }else{ int length=length_text(txt); //Check index with maxlength if(index>length){ return NULL; }else{ //Initialize stack createstack(); text_t * uppernode; text_t * sel_node; text_t * other_node; while(txt->right!=NULL){ push(txt); uppernode=txt; if(index<=txt->key){ sel_node=txt->left; other_node=txt->right; txt->key=txt->key-1; txt=txt->left; }else{ index=index-txt->key; sel_node=txt->right; other_node=txt->left; txt=txt->right; } } //Pop the last node pop(); uppernode->left=other_node->left; uppernode->right=other_node->right; uppernode->key=other_node->key; uppernode->height=other_node->height; text_t * tmp_node=NULL; int finished=0; while( !stack_empty() && !finished ){ int tmp_height, old_height; tmp_node = pop(); old_height= tmp_node->height; if( tmp_node->left->height - tmp_node->right->height == 2 ) { if( tmp_node->left->left->height - tmp_node->right->height == 1 ) { right_rotation( tmp_node ); tmp_node->right->height = tmp_node->right->left->height + 1; tmp_node->height = tmp_node->right->height + 1; } else { left_rotation( tmp_node->left ); right_rotation( tmp_node ); tmp_height = tmp_node->left->left->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } }else if( tmp_node->left->height - tmp_node->right->height == -2 ) { if( tmp_node->right->right->height - tmp_node->left->height == 1 ) { left_rotation( tmp_node ); tmp_node->left->height =tmp_node->left->right->height + 1; tmp_node->height = tmp_node->left->height + 1; } else { right_rotation( tmp_node->right ); left_rotation( tmp_node ); tmp_height = tmp_node->right->right->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } } else /* update height even if there was no rotation */ { if( tmp_node->left->height > tmp_node->right->height ) tmp_node->height = tmp_node->left->height + 1; else tmp_node->height = tmp_node->right->height + 1; } if( tmp_node->height == old_height ) finished = 1; } remove_stack(); return (char *)sel_node->left; /* if(index-txt->key==1){ }else{ //Node not found printf("shouldn't come here"); }*/ } } }
/* Inserts the line before the line of number index, if such a line exists, to new line, renumbering all lines after that line. If no such line exists, it appends new line as new last line */ void insert_line(text_t *txt, int index, char * new_line) { if(txt==NULL){ //printf("Should not come here"); return NULL; }else if( txt->left == NULL ) { if(index>length_text(txt)+1){ index=length_text(txt)+1; } txt->left = (struct text_t *) new_line; txt->key = 0; txt->height = 0; txt->right = NULL; }else{ //check max line if(index>length_text(txt)+1){ index=length_text(txt)+1; } createstack(); while(txt->right!=NULL){ push(txt); if(index<=txt->key){ txt->key=txt->key+1; txt=txt->left; }else if(index>txt->key){ index=index-txt->key; txt=txt->right; } } //create a new Node text_t * old_node=malloc(sizeof(text_t)); old_node->key=0; old_node->left=txt->left; old_node->right=txt->right; old_node->height=0; text_t * new_node=malloc(sizeof(text_t)); new_node->key=0; new_node->left=(struct text_t *)new_line; new_node->right=NULL; new_node->height=0; if(index-txt->key==0){ txt->left=new_node; txt->right=old_node; txt->height=height(txt); }else if(index-txt->key==1){ txt->left=new_node; txt->right=old_node; txt->height=height(txt); }else{ txt->left=old_node; txt->right=new_node; txt->height=height(txt); } txt->key=1; //balance the tree //Need stack text_t * tmp_node=NULL; int finished =0; while( !stack_empty() && !finished ){ int tmp_height, old_height; tmp_node = pop(); old_height= tmp_node->height; if( tmp_node->left->height - tmp_node->right->height == 2 ) { if( tmp_node->left->left->height - tmp_node->right->height == 1 ) { right_rotation( tmp_node ); tmp_node->right->height = tmp_node->right->left->height + 1; tmp_node->height = tmp_node->right->height + 1; } else { left_rotation( tmp_node->left ); right_rotation( tmp_node ); tmp_height = tmp_node->left->left->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } }else if( tmp_node->left->height - tmp_node->right->height == -2 ) { if( tmp_node->right->right->height - tmp_node->left->height == 1 ) { left_rotation( tmp_node ); tmp_node->left->height =tmp_node->left->right->height + 1; tmp_node->height = tmp_node->left->height + 1; } else { right_rotation( tmp_node->right ); left_rotation( tmp_node ); tmp_height = tmp_node->right->right->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } } else /* update height even if there was no rotation */ { if( tmp_node->left->height > tmp_node->right->height ) tmp_node->height = tmp_node->left->height + 1; else tmp_node->height = tmp_node->right->height + 1; } if( tmp_node->height == old_height ) finished = 1; } remove_stack(); } }
int insert(tree_node_t *tree, key_t new_key, object_t *new_object) { if( tree->left == NULL ) { tree->left = (tree_node_t *) new_object; tree->key = new_key; tree->color = black; /* root is always black */ tree->right = NULL; } else { tree_node_t *current, *next_node, *upper; current = tree; upper = NULL; while( current->right != NULL ) { if( new_key < current->key ) next_node = current->left; else next_node = current->right; if( current->color == black ) { if( current->left->color == black || current->right->color == black ) { upper = current; current = next_node; } else /* current->left and current->right red */ { /* need rebalance */ if( upper == NULL ) /* current is root */ { current->left->color = black; current->right->color = black; upper = current; } else if (current->key < upper->key ) { /* current left of upper */ if( current == upper->left ) { current->left->color = black; current->right->color = black; current->color = red; } else if( current == upper->left->left ) { right_rotation( upper ); upper->left->color = red; upper->right->color = red; upper->left->left->color = black; upper->left->right->color = black; } else /* current == upper->left->right */ { left_rotation( upper->left ); right_rotation( upper ); upper->left->color = red; upper->right->color = red; upper->right->left->color = black; upper->left->right->color = black; } } else /* current->key >= upper->key */ { /* current right of upper */ if( current == upper->right ) { current->left->color = black; current->right->color = black; current->color = red; } else if( current == upper->right->right ) { left_rotation( upper ); upper->left->color = red; upper->right->color = red; upper->right->left->color = black; upper->right->right->color = black; } else /* current == upper->right->left */ { right_rotation( upper->right ); left_rotation( upper ); upper->left->color = red; upper->right->color = red; upper->right->left->color = black; upper->left->right->color = black; } } /* end rebalancing */ current = next_node; upper = current; /*two black lower neighbors*/ } } else /* current red */ { current = next_node; /*move down */ } } /* end while; reached leaf. always arrive on black leaf*/ /* found the candidate leaf. Test whether key distinct */ if( current->key == new_key ) return( -1 ); /* key is distinct, now perform the insert */ { tree_node_t *old_leaf, *new_leaf; old_leaf = get_node(); old_leaf->left = current->left; old_leaf->key = current->key; old_leaf->right = NULL; old_leaf->color = red; new_leaf = get_node(); new_leaf->left = (tree_node_t *) new_object; new_leaf->key = new_key; new_leaf->right = NULL; new_leaf->color = red; if( current->key < new_key ) { current->left = old_leaf; current->right = new_leaf; current->key = new_key; } else { current->left = new_leaf; current->right = old_leaf; } } } return( 0 ); }
int insert_tree(text_t *tree, char *new_object, key_t new_key) { text_t *tmp_node; text_t * path_stack[100]; int path_st_p = 0; tmp_node = tree; while (tmp_node->right != NULL) { path_stack[path_st_p++] = tmp_node; if (new_key < tmp_node->key) tmp_node = tmp_node->left; else tmp_node = tmp_node->right; } /* found the candidate leaf. Test whether key distinct */ if (tmp_node->key == new_key) return (-1); /* key is distinct, now perform the insert */ { text_t *old_leaf, *new_leaf; old_leaf = get_node(); old_leaf->left = tmp_node->left; old_leaf->key = tmp_node->key; old_leaf->right = NULL; old_leaf->weight = 1; new_leaf = get_node(); new_leaf->left = (text_t *) new_object; new_leaf->key = new_key; new_leaf->right = NULL; new_leaf->weight = 1; if (tmp_node->key < new_key) { tmp_node->left = old_leaf; tmp_node->right = new_leaf; tmp_node->key = new_key; } else { tmp_node->left = new_leaf; tmp_node->right = old_leaf; } tmp_node->weight = 2; } /* rebalance */ while (path_st_p > 0) { tmp_node = path_stack[--path_st_p]; tmp_node->weight = tmp_node->left->weight + tmp_node->right->weight; if (tmp_node->right->weight < ALPHA * tmp_node->weight) { if (tmp_node->left->left->weight > (ALPHA + EPSILON) * tmp_node->weight) { right_rotation(tmp_node); tmp_node->right->weight = tmp_node->right->left->weight + tmp_node->right->right->weight; } else { left_rotation(tmp_node->left); right_rotation(tmp_node); tmp_node->right->weight = tmp_node->right->left->weight + tmp_node->right->right->weight; tmp_node->left->weight = tmp_node->left->left->weight + tmp_node->left->right->weight; } } else if (tmp_node->left->weight < ALPHA * tmp_node->weight) { if (tmp_node->right->right->weight > (ALPHA + EPSILON) * tmp_node->weight) { left_rotation(tmp_node); tmp_node->left->weight = tmp_node->left->left->weight + tmp_node->left->right->weight; } else { right_rotation(tmp_node->right); left_rotation(tmp_node); tmp_node->right->weight = tmp_node->right->left->weight + tmp_node->right->right->weight; tmp_node->left->weight = tmp_node->left->left->weight + tmp_node->left->right->weight; } } } return (0); }
int insert(m_tree_t *tree, key_t new_key, intervalListNode *newInterval) { m_tree_t *tmp_node; stack_t *s = create_stack(); stack_t *rotate_s = create_stack(); if( tree->left == NULL ) { intervalListNode *interval =(intervalListNode*)malloc(sizeof(intervalListNode)); if(interval==NULL) printf("insert malloc failed!\n"); interval->leftPoint = newInterval->leftPoint; interval->rightPoint = newInterval->rightPoint; interval->next = NULL; tree->left = (m_tree_t *) interval; tree->key = new_key; tree->right = NULL; tree->leftMin = newInterval->leftPoint; tree->rightMax = newInterval->rightPoint; tree->l = -2147483648; // to represent -infinity tree->r = 2147483647; // to represent infinity updateLeafMeasure(tree); } else { tmp_node = tree; while( tmp_node->right != NULL ) { push(tmp_node, s); push(tmp_node, rotate_s); if( new_key < tmp_node->key ) tmp_node = tmp_node->left; else tmp_node = tmp_node->right; } /* found the candidate leaf. Test whether key distinct */ if( tmp_node->key == new_key ) { // if the key exists, then add the current interval to the interval list. addAssociatedInterval(tmp_node, newInterval); tmp_node->leftMin = min(tmp_node->leftMin, newInterval->leftPoint); tmp_node->rightMax = max(tmp_node->rightMax, newInterval->rightPoint); updateLeafMeasure(tmp_node); } /* key is distinct, now perform the insert */ else { m_tree_t *old_leaf, *new_leaf; old_leaf = get_node(); old_leaf->left = tmp_node->left; old_leaf->key = tmp_node->key; old_leaf->right = NULL; old_leaf->height = 0; old_leaf->leftMin = tmp_node->leftMin; old_leaf->rightMax = tmp_node->rightMax; new_leaf = get_node(); addAssociatedInterval(new_leaf, newInterval); new_leaf->key = new_key; new_leaf->right = NULL; new_leaf->height = 0; new_leaf->leftMin = newInterval->leftPoint; new_leaf->rightMax = newInterval->rightPoint; if( tmp_node->key < new_key ) { tmp_node->left = old_leaf; tmp_node->right = new_leaf; tmp_node->key = new_key; old_leaf->l = tmp_node->l; old_leaf->r = new_key; new_leaf->l = new_key; new_leaf->r = tmp_node->r; } else { tmp_node->left = new_leaf; tmp_node->right = old_leaf; new_leaf->l = tmp_node->l; new_leaf->r = tmp_node->key; old_leaf->l = tmp_node->key; old_leaf->r = tmp_node->r; } updateLeafMeasure(old_leaf); updateLeafMeasure(new_leaf); tmp_node->height = 1; tmp_node->leftMin = min(tmp_node->left->leftMin,tmp_node->right->leftMin); tmp_node->rightMax = max(tmp_node->left->rightMax,tmp_node->right->rightMax); //push(tmp_node, s); updateInternalMeasure(tmp_node); tmp_node->leftMin = min(tmp_node->left->leftMin,tmp_node->right->leftMin); tmp_node->rightMax = max(tmp_node->left->rightMax,tmp_node->right->rightMax); } // update measures while(!stack_empty(s)) { tmp_node = top(s); pop(s); updateInternalMeasure(tmp_node); tmp_node->leftMin = min(tmp_node->left->leftMin,tmp_node->right->leftMin); tmp_node->rightMax = max(tmp_node->left->rightMax,tmp_node->right->rightMax); } // rebalance int finished = 0; while(!stack_empty(rotate_s) && !finished) { tmp_node = top(rotate_s); pop(rotate_s); int tmp_height, old_height; old_height= tmp_node->height; if( tmp_node->left->height - tmp_node->right->height == 2 ) { if( tmp_node->left->left->height - tmp_node->right->height == 1 ) { right_rotation( tmp_node ); tmp_node->right->height = tmp_node->right->left->height + 1; tmp_node->height = tmp_node->right->height + 1; } else { left_rotation( tmp_node->left ); right_rotation( tmp_node ); tmp_height = tmp_node->left->left->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } } else if( tmp_node->left->height - tmp_node->right->height == -2 ) { if( tmp_node->right->right->height - tmp_node->left->height == 1 ) { left_rotation( tmp_node ); tmp_node->left->height = tmp_node->left->right->height + 1; tmp_node->height = tmp_node->left->height + 1; } else { right_rotation( tmp_node->right ); left_rotation( tmp_node ); tmp_height = tmp_node->right->right->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } } else /* update height even if there was no rotation */ { if( tmp_node->left->height > tmp_node->right->height ) tmp_node->height = tmp_node->left->height + 1; else tmp_node->height = tmp_node->right->height + 1; } if( tmp_node->height == old_height ) finished = 1; } } remove_stack(s); remove_stack(rotate_s); return 0; }
void insert_line(tree_node *tree, int new_key, char *new_line){ //Inserts the line before the line of the number `new_key`, if such //a line exists, to `new_line` , renumbering all lines after that line. //If no such line exists, it `appends(new_line)` as last line. tree_node *temp_node; int finished; if(tree->left == NULL){ //empty tree. no children tree->left = (tree_node *) new_line; //tree->key = new_key; tree->key +=1; tree->height = 0; tree->right = NULL; } if(tree->key == 1){ //the root has one child tree_node *left_child, *right_child; left_child = get_node(); right_child = get_node(); left_child->left = tree->left; left_child->key = tree->key; right_child->left = (tree_node *) new_line; right_child->key += 1; tree->left = left_child; tree->right = right_child; tree->key += 1; } if (tree->key < new_key){ //go to the left branch append_line(tree, new_line); } else{ //go to the right branch tree_node *stack[STACK_MAX]; int stack_ptr = 0; temp_node = tree; while(temp_node->right != NULL){ stack[stack_ptr++] = temp_node; temp_node->key += 1; if (new_key <= temp_node->left->key){ temp_node = temp_node->left; } else{ new_key -= temp_node->left->key; temp_node = temp_node->right; } } tree_node *left_child, *right_child; left_child = get_node(); right_child = get_node(); left_child->left = temp_node->left; left_child->key = temp_node->key; right_child->left = (tree_node *) new_line; right_child->key += 1; temp_node->left = left_child; temp_node->right = right_child; temp_node->key += 1; temp_node->height = 1; //rebalance tree finished = 0; while(stack_ptr > 0 && !finished){ int temp_height , old_height; temp_node = stack[--stack_ptr]; old_height = temp_node->height; if(temp_node->left->height - temp_node->right->height == 2){ if (temp_node->left->left->height - temp_node->right->height == 1){ right_rotation(temp_node); temp_node->right->height = temp_node->right->left->height + 1; temp_node->height = temp_node->right->height + 1; } else{ left_rotation(temp_node->left); right_rotation(temp_node); temp_height = temp_node->left->left->height; temp_node->left->height = temp_height + 1; temp_node->right->height = temp_height + 1; temp_node->height = temp_height + 2; } } else if (temp_node->left->height - temp_node->right->height == -2){ if (temp_node->right->right->height - temp_node->left->height == 1){ left_rotation(temp_node); temp_node->left->height = temp_node->left->right->height + 1; temp_node->height = temp_node->left->height + 1; } else{ right_rotation(temp_node->right); left_rotation(temp_node); temp_height = temp_node->right->right->height; temp_node->left->height = temp_height + 1; temp_node->right->height = temp_height + 1; temp_node->height = temp_height + 2; } } else{ //if no rotation needed, update height if (temp_node->left->height > temp_node->right->height){ temp_node->height = temp_node->left->height + 1; } else{ temp_node->height = temp_node->right->height + 1; } } if (temp_node->height == old_height){ finished = 1; } } } }
void append_line(text_t *txt, char *new_line){ text_t *tmp_node; text_t *old_leaf, *new_leaf; int finished; text_t * path_stack[100]; int path_st_p; if(txt->left == NULL){ txt->left = (text_t *)new_line; txt->key = 1; txt->height = 0; txt->right = NULL; }else{ path_st_p = 0; tmp_node = txt; while(tmp_node->right != NULL){ path_stack[path_st_p++] = tmp_node; tmp_node = tmp_node->right; } { old_leaf = get_node(); old_leaf->left = tmp_node->left; old_leaf->key = tmp_node->key; old_leaf->right = NULL; old_leaf->height = 0; new_leaf = get_node(); new_leaf->left = (text_t *)new_line; new_leaf->key = 1; new_leaf->right = NULL; new_leaf->height = 0; tmp_node->left = old_leaf; tmp_node->right = new_leaf; tmp_node->key = old_leaf->key + new_leaf->key; tmp_node->height = 1; } // rebalance the tree finished = 0; while( path_st_p > 0 && !finished ){ int tmp_height, old_height; tmp_node = path_stack[--path_st_p]; // add new line update key tmp_node->key = tmp_node->left->key + tmp_node->right->key; old_height= tmp_node->height; if( tmp_node->left->height - tmp_node->right->height == 2 ){ if( tmp_node->left->left->height - tmp_node->right->height == 1 ) { right_rotation( tmp_node ); tmp_node->right->height = tmp_node->right->left->height + 1; tmp_node->height = tmp_node->right->height + 1; }else{ left_rotation( tmp_node->left ); right_rotation( tmp_node ); tmp_height = tmp_node->left->left->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } }else if ( tmp_node->left->height - tmp_node->right->height == -2 ){ if( tmp_node->right->right->height - tmp_node->left->height == 1 ){ left_rotation( tmp_node ); tmp_node->left->height = tmp_node->left->right->height + 1; tmp_node->height = tmp_node->left->height + 1; //add line to update key. tmp_node->key = tmp_node->left->key; tmp_node->left->key = tmp_node->left->left->key + tmp_node->left->right->key; }else{ right_rotation( tmp_node->right ); left_rotation( tmp_node ); tmp_height = tmp_node->right->right->height; tmp_node->left->height = tmp_height + 1; tmp_node->right->height = tmp_height + 1; tmp_node->height = tmp_height + 2; } }else{ if( tmp_node->left->height > tmp_node->right->height ){ tmp_node->height = tmp_node->left->height + 1; }else{ tmp_node->height = tmp_node->right->height + 1; } } if( tmp_node->height == old_height ){ finished = 1; } } while( path_st_p > 0){ tmp_node = path_stack[--path_st_p]; // add new line update key tmp_node->key = tmp_node->left->key + tmp_node->right->key; } } }
void append_line(tree_node *tree, char *new_line){ //appends `new_line` as a new last line tree_node *temp_node; int finished; if(tree->left == NULL){ //empty tree tree->left = (tree_node *) new_line; tree->key += 1; tree->right = NULL; tree->height = 0; } else{ temp_node = tree; tree_node *stack[STACK_MAX]; int stack_ptr = 0; while (temp_node->right != NULL){ stack[stack_ptr++] = temp_node; temp_node->key += 1; temp_node = temp_node->right; } tree_node *left_child, *right_child; left_child = get_node(); right_child = get_node(); left_child->left = temp_node->left; left_child->key = temp_node->key; right_child->left = (tree_node *)new_line; right_child->key += 1; temp_node->left = left_child; temp_node->right = right_child; temp_node->key += 1; temp_node->height = 1; //rebalance tree finished = 0; while (stack_ptr > 0 && !finished){ int temp_height, old_height; temp_node = stack[--stack_ptr]; old_height = temp_node->height; if(temp_node->left->height - temp_node->right->height == 2){ if (temp_node->left->left->height - temp_node->right->height == 1){ right_rotation(temp_node); temp_node->right->height = temp_node->right->left->height + 1; temp_node->height = temp_node->right->height + 1; } else{ left_rotation(temp_node->left); right_rotation(temp_node); temp_height = temp_node->left->left->height; temp_node->left->height = temp_height + 1; temp_node->right->height = temp_height + 1; temp_node->height = temp_height + 2; } } else if (temp_node->left->height - temp_node->right->height == -2){ if (temp_node->right->right->height - temp_node->left->height == 1){ left_rotation(temp_node); temp_node->left->height = temp_node->left->right->height + 1; temp_node->height = temp_node->left->height + 1; } else{ right_rotation(temp_node->right); left_rotation(temp_node); temp_height = temp_node->right->right->height; temp_node->left->height = temp_height + 1; temp_node->right->height = temp_height + 1; temp_node->height = temp_height + 2; } } else{ //if no rotation needed, update height if (temp_node->left->height > temp_node->right->height){ temp_node->height = temp_node->left->height + 1; } else{ temp_node->height = temp_node->right->height + 1; } } if (temp_node->height == old_height){ finished = 1; } } } }
object_t * find (tree_node_t * tree, key_t query_key) { int finished = 0; if (tree->object == NULL) return (NULL); /* tree empty */ else { tree_node_t *current_node, *stack_top, *tmp_stack; stack_top = NULL; current_node = tree; while (!finished) { tmp_stack = get_node (); tmp_stack->right = stack_top; tmp_stack->left = current_node; stack_top = tmp_stack; if (query_key < current_node->key && current_node->left != NULL) current_node = current_node->left; else if (query_key > current_node->key && current_node->right != NULL) current_node = current_node->right; else finished = 1; } if (current_node->key != query_key) return (NULL); else { tree_node_t *upper, *upper2; tmp_stack = stack_top; stack_top = stack_top->right; return_node (tmp_stack); while (current_node != tree) { upper = stack_top->left; tmp_stack = stack_top; stack_top = stack_top->right; return_node (tmp_stack); if (upper == tree) { if (upper->left == current_node) right_rotation (upper); else left_rotation (upper); current_node = upper; } else { upper2 = stack_top->left; tmp_stack = stack_top; stack_top = stack_top->right; return_node (tmp_stack); if (upper == upper2->left) { if (current_node == upper->left) right_rotation (upper2); else left_rotation (upper); right_rotation (upper2); } else { if (current_node == upper->right) left_rotation (upper2); else right_rotation (upper); left_rotation (upper2); } current_node = upper2; } } return (current_node->object); } } }