Exemple #1
0
// 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);
	}
}
Exemple #2
0
static void right_left_rotation(avl_node *node)
{
	avl_node *right_node = node->right;

	right_rotation(right_node);
	left_rotation(node);
}
Exemple #3
0
static void left_right_rotation(avl_node *node)
{
	avl_node *left_node = node->left;
	
	left_rotation(left_node);
	right_rotation(node);
}
Exemple #4
0
/*
 * 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);
		}
	}
}
Exemple #5
0
  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);





}
Exemple #7
0
/* 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);
	}
}
Exemple #8
0
/* 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;
		}
	}
}
Exemple #9
0
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;
}
Exemple #10
0
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;
		}

	}
}
Exemple #11
0
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;
		}
	}
}
Exemple #13
0
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 );
}
Exemple #14
0
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);

}
Exemple #20
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;
			}
		}

	}
}
Exemple #22
0
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;
			}

		}
	}
}
Exemple #24
0
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);
        }
    }
}