Beispiel #1
0
Node* fixAVL(Node* node)

{
	if (node != NULL)
	{
		node -> factor = getFactor(node);

		if(node -> factor == 2)
		{
			node -> left -> factor = getFactor(node -> left);
			if(node -> left -> factor > 0)
			{
				node = rotationRight(node);
			}

			else
			{
				node = rotationRight_Right(node);
			}

		}

		else if(node -> factor == -2)
		{
			node -> right -> factor = getFactor(node -> right);

			if(node -> right -> factor < 0)
			{
				node = rotationLeft(node);
			}

			else
			{
				node = rotationLeft_Left(node);
			}
		}

		node -> left = fixAVL(node -> left);
		node -> right = fixAVL(node -> right);
	}

	return node;
}
// usuwa wezel z zadanymi danymi
bool DrzewoCzerCzar::remove(int data)
{
	Node* X = find(data);

	if (X != NULL)
	{
		Node * W, *Y, *Z;

		if ((X->left == guard) || (X->right == guard)) Y = X;
		else                                    Y = poprzednik(X);

		if (Y->left != guard) Z = Y->left;
		else              Z = Y->right;

		Z->up = Y->up;

		if (Y->up == guard) root = Z;
		else if (Y == Y->up->left) Y->up->left = Z;
		else                      Y->up->right = Z;

		if (Y != X) X->data = Y->data;

		// przywracanie struktury drzewa czerwono-czarnego
		if (Y->color == 'b')
		while ((Z != root) && (Z->color == 'b'))
		{
			//opoznienie do pomiarow
			for (int i = 0; i < 2000; i++);

			if (Z == Z->up->left)
			{
				W = Z->up->right;

				if (W->color == 'r')
				{              
					W->color = 'b';
					Z->up->color = 'r';
					rotationLeft(Z->up);
					W = Z->up->right;
				}

				if ((W->left->color == 'b') && (W->right->color == 'b'))
				{            
					W->color = 'r';
					Z = Z->up;
					continue;
				}

				if (W->right->color == 'b')
				{            
					W->left->color = 'b';
					W->color = 'r';
					rotationRight(W);
					W = Z->up->right;
				}

				W->color = Z->up->color;
				Z->up->color = 'b';
				W->right->color = 'b';
				rotationLeft(Z->up);
				Z = root;  
			}
			else
			{             
				W = Z->up->left;

				if (W->color == 'r')
				{      
					W->color = 'b';
					Z->up->color = 'r';
					rotationRight(Z->up);
					W = Z->up->left;
				}

				if ((W->left->color == 'b') && (W->right->color == 'b'))
				{        
					W->color = 'r';
					Z = Z->up;
					continue;
				}

				if (W->left->color == 'b')
				{      
					W->right->color = 'b';
					W->color = 'r';
					rotationLeft(W);
					W = Z->up->left;
				}

				W->color = Z->up->color; 
				Z->up->color = 'b';
				W->left->color = 'b';
				rotationRight(Z->up);
				Z = root;         
			}
		}

		Z->color = 'b';

		delete Y;

		return true;
	}

	return false;
}
// wstawianie elementu do drzewa czerwono-czarnego
void DrzewoCzerCzar::insert(int data)
{
	Node* tempRoot = guard;
	Node* temp = root;
	// wstawianie elementu jak do BST
	while (temp != guard)
	{
		//opoznienie do pomiarow
		for (int i = 0; i<1000; i++);

		tempRoot = temp;
		if (data > temp->data)
			temp = temp->right;
		else
			temp = temp->left;
	}

	if (tempRoot == guard)
	{
		root = new Node();
		root->up = guard; root->left = guard; root->right = guard;
		root->data = data; root->color = 'b';
		return;
	}
	else
	{
		if (data > tempRoot->data)
		{
			tempRoot->right = new Node();
			temp = tempRoot->right;
		}
		else
		{
			tempRoot->left = new Node();
			temp = tempRoot->left;
		}

		temp->left = guard; temp->right = guard;
		temp->up = tempRoot; temp->data = data;
		temp->color = 'r';
	}

	// przywracanie warunkow drzewa czerwono-czarnego
	while (true)
	{
		//opoznienie do pomiarow
		for (int i = 0; i<1000; i++);

		if (temp->up->color == 'b') return;
		else
		{
			// ustalenie wujka
			Node* wujek = NULL;
			char stronaPokr;	// l - lewy syn, p - prawy syn
			int przypadek = -1; // 0 - domyslnie, 1 - przypadek lustrzany
			if (temp->up->up->left->left == temp)
			{
				stronaPokr = 'l';
				wujek = temp->up->up->right;
				przypadek = 0;
			}
			else if (temp->up->up->left->right == temp)
			{
				stronaPokr = 'p';
				wujek = temp->up->up->right;
				przypadek = 0;
			}
			else if (temp->up->up->right->left == temp)
			{
				stronaPokr = 'l';
				wujek = temp->up->up->left;
				przypadek = 1;
			}
			else if (temp->up->up->right->right == temp)
			{
				stronaPokr = 'p';
				wujek = temp->up->up->left;
				przypadek = 1;
			}
			else return;

			// Przypadek I: wujek czerwony
			if (wujek->color == 'r')
			{
				temp->up->color = 'b';		// kolor ojca
				wujek->color = 'b';			// kolor wujka
				temp->up->up->color = 'r';	// kolor dziadka
				if (temp->up->up == root)
				{
					temp->up->up->color = 'b';
					return;
				}
				else
				{
					temp = temp->up->up;
					continue;
				}
			}
			// Przypadek II: wujek czarny, a temp jest prawym dzieckiem (lub lustro)
			else if (wujek->color == 'b' && stronaPokr == 'p' && przypadek == 0)
			{
				temp = temp->up;
				rotationLeft(temp);
				continue;
			}
			else if (wujek->color == 'b' && stronaPokr == 'l' && przypadek == 1)
			{
				temp = temp->up;
				rotationRight(temp);
				continue;
			}
			// Przypadek III: wujek jest czarny, a temp jest lewym dzieckiem (lub lustro)
			else if (wujek->color == 'b' && stronaPokr == 'l' && przypadek == 0)
			{
				if (temp->up->up != guard)
				{
					if (temp->up->up->color == 'r')
						temp->up->up->color = 'b';
					else
						temp->up->up->color = 'r';
				}

				if (temp->up != guard)
				{
					if (temp->up->color == 'r')
						temp->up->color = 'b';
					else
						temp->up->color = 'r';
				}

				rotationRight(temp->up->up);

				return;
			}
			else if (wujek->color == 'b' && stronaPokr == 'p' && przypadek == 1)
			{
				if (temp->up->up != guard)
				{
					if (temp->up->up->color == 'r')
						temp->up->up->color = 'b';
					else
						temp->up->up->color = 'r';
				}

				if (temp->up != guard)
				{
					if (temp->up->color == 'r')
						temp->up->color = 'b';
					else
						temp->up->color = 'r';
				}

				rotationLeft(temp->up->up);

				return;
			}
		}
	}
}