void RBT_RebuildAfterInsert(RBTNode** Root, RBTNode* X)
{
	while (X != (*Root) && X->Parent->Color == RED)
	{
		if (X->Parent == X->Parent->Parent->Left)
		{
			RBTNode* Uncle = X->Parent->Parent->Right;
			if (Uncle->Color == RED)
			{
				X->Parent->Color = BLACK;
				Uncle->Color = BLACK;
				X->Parent->Parent->Color = RED;

				X = X->Parent->Parent;
			}
			else
			{
				if (X == X->Parent->Right)
				{
					X = X->Parent;
					RBT_RotateLeft(Root, X);
				}

				X->Parent->Color = BLACK;
				X->Parent->Parent->Color = RED;

				RBT_RotateRight(Root, X->Parent->Parent);
			}
		}
		else
		{
			RBTNode* Uncle = X->Parent->Parent->Left;
			if (Uncle->Color == RED)
			{
				X->Parent->Color = BLACK;
				Uncle->Color = BLACK;
				X->Parent->Parent->Color = RED;

				X = X->Parent->Parent;
			}
			else
			{
				if (X == X->Parent->Left)
				{
					X = X->Parent;
					RBT_RotateRight(Root, X);
				}

				X->Parent->Color = BLACK;
				X->Parent->Parent->Color = RED;
				RBT_RotateLeft(Root, X->Parent->Parent);
			}
		}
	}

	(*Root)->Color = BLACK;
}
void RBT_RebuildAfterRemove(RBTNode** Root, RBTNode* Successor)
{
	RBTNode* Sibling = NULL;

	while (Successor->Parent != NULL && Successor->Color == BLACK)
	{
		if (Successor == Successor->Parent->Left)
		{
			Sibling = Successor->Parent->Right;

			if (Sibling->Color == RED)
			{
				Sibling->Color = BLACK;
				Successor->Parent->Color = RED;
				RBT_RotateLeft(Root, Successor->Parent);
			}
			else
			{
				if (Sibling->Left->Color == BLACK &&
					Sibling->Right->Color == BLACK)
				{
					Sibling->Color = RED;
					Successor = Successor->Parent;
				}
				else
				{
					if (Sibling->Left->Color == RED)
					{
						Sibling->Left->Color = BLACK;
						Sibling->Color = RED;

						RBT_RotateRight(Root, Sibling);
						Sibling = Successor->Parent->Right;
					}

					Sibling->Color = Successor->Parent->Color;
					Successor->Parent->Color = BLACK;
					Sibling->Right->Color = BLACK;
					RBT_RotateLeft(Root, Successor->Parent);
					Successor = (*Root);
				}
			}
		}
		else
		{
			Sibling = Successor->Parent->Left;

			if (Sibling->Color == RED)
			{
				Sibling->Color = BLACK;
				Successor->Parent->Color = RED;
				RBT_RotateRight(Root, Successor->Parent);
			}
			else
			{
				if (Sibling->Right->Color == BLACK &&
					Sibling->Left->Color == BLACK)
				{
					Sibling->Color = RED;
					Successor = Successor->Parent;
				}
				else
				{
					if (Sibling->Right->Color == RED)
					{
						Sibling->Right->Color = BLACK;
						Sibling->Color = RED;

						RBT_RotateLeft(Root, Sibling);
						Sibling = Successor->Parent->Left;
					}

					Sibling->Color = Successor->Parent->Color;
					Successor->Parent->Color = BLACK;
					Sibling->Left->Color = BLACK;
					RBT_RotateRight(Root, Successor->Parent);
					Successor = (*Root);
				}
			}
		}
	}

	Successor->Color = BLACK;
}
Beispiel #3
0
RBT_NODE_S* RBT_InsertRebalance(RBT_NODE_S *pstNode, RBT_NODE_S *pstRoot)
{
    RBT_NODE_S *pstParent = NULL; 
    RBT_NODE_S *pstGParent = NULL;
    RBT_NODE_S *pstUncleNode = NULL;
    RBT_NODE_S* pstTmp = NULL;

    while ((pstParent = pstNode->pstParent) && pstParent->enColor == RED)
    {
        pstGParent = pstParent->pstParent;

        if (pstParent == pstGParent->pstLeft)
        {
            pstUncleNode = pstGParent->pstRight;
            if (pstUncleNode && pstUncleNode->enColor == RED)
            {
                pstUncleNode->enColor = BLACK;
                pstParent->enColor = BLACK;
                pstGParent->enColor = RED;
                pstNode = pstGParent;
            }
            else
            {
                if (pstParent->pstRight == pstNode)
                {
                    pstRoot = RBT_RotateLeft(pstParent, pstRoot);
                    pstTmp = pstParent;
                    pstParent = pstNode;
                    pstNode = pstTmp;
                }

                pstParent->enColor = BLACK;
                pstGParent->enColor = RED;
                pstRoot = RBT_RotateRight(pstGParent, pstRoot);
            }
        } 
        else 
        {
            pstUncleNode = pstGParent->pstLeft;
            if (pstUncleNode && pstUncleNode->enColor == RED)
            {
                pstUncleNode->enColor = BLACK;
                pstParent->enColor = BLACK;
                pstGParent->enColor = RED;
                pstNode = pstGParent;
            }
            else
            {
                if (pstParent->pstLeft == pstNode)
                {
                    pstRoot = RBT_RotateRight(pstParent, pstRoot);
                    pstTmp = pstParent;
                    pstParent = pstNode;
                    pstNode = pstTmp;
                }

                pstParent->enColor = BLACK;
                pstGParent->enColor = RED;
                pstRoot = RBT_RotateLeft(pstGParent, pstRoot);
            }
        }
    }

    pstRoot->enColor = BLACK;

    return pstRoot;
}
Beispiel #4
0
RBT_NODE_S* RBT_EraseRebalance(RBT_NODE_S *pstNode, RBT_NODE_S *pstParent, RBT_NODE_S *pstRoot)
{
    RBT_NODE_S *pstOther = NULL;
    RBT_NODE_S *pstOldLeft = NULL;
    RBT_NODE_S *pstOldRight = NULL;

    while ((!pstNode || pstNode->enColor == BLACK) && pstNode != pstRoot)
    {
        if (pstParent->pstLeft == pstNode)
        {
            pstOther = pstParent->pstRight;
            if (pstOther->enColor == RED)
            {
                pstOther->enColor = BLACK;
                pstParent->enColor = RED;
                pstRoot = RBT_RotateLeft(pstParent, pstRoot);
                pstOther = pstParent->pstRight;
            }
            if ((!pstOther->pstLeft || pstOther->pstLeft->enColor == BLACK) &&
                (!pstOther->pstRight || pstOther->pstRight->enColor == BLACK))
            {
                pstOther->enColor = RED;
                pstNode = pstParent;
                pstParent = pstNode->pstParent;
            }
            else
            {
                if (!pstOther->pstRight || pstOther->pstRight->enColor == BLACK)
                {
                    if ((pstOldLeft = pstOther->pstLeft))
                    {
                        pstOldLeft->enColor = BLACK;
                    }
                    pstOther->enColor = RED;
                    pstRoot = RBT_RotateRight(pstOther, pstRoot);
                    pstOther = pstParent->pstRight;
                }
                pstOther->enColor = pstParent->enColor;
                pstParent->enColor = BLACK;
                if (pstOther->pstRight)
                {
                    pstOther->pstRight->enColor = BLACK;
                }
                pstRoot = RBT_RotateLeft(pstParent, pstRoot);
                pstNode = pstRoot;
                break;
            }
        }
        else
        {
            pstOther = pstParent->pstLeft;
            if (pstOther->enColor == RED)
            {
                pstOther->enColor = BLACK;
                pstParent->enColor = RED;
                pstRoot = RBT_RotateRight(pstParent, pstRoot);
                pstOther = pstParent->pstLeft;
            }
            if ((!pstOther->pstLeft || pstOther->pstLeft->enColor == BLACK) &&
                (!pstOther->pstRight || pstOther->pstRight->enColor == BLACK))
            {
                pstOther->enColor = RED;
                pstNode = pstParent;
                pstParent = pstNode->pstParent;
            }
            else
            {
                if (!pstOther->pstLeft || pstOther->pstLeft->enColor == BLACK)
                {
                    if ((pstOldRight = pstOther->pstRight))
                    {
                        pstOldRight->enColor = BLACK;
                    }
                    pstOther->enColor = RED;
                    pstRoot = RBT_RotateLeft(pstOther, pstRoot);
                    pstOther = pstParent->pstLeft;
                }
                pstOther->enColor = pstParent->enColor;
                pstParent->enColor = BLACK;
                if (pstOther->pstLeft)
                {
                    pstOther->pstLeft->enColor = BLACK;
                }
                pstRoot = RBT_RotateRight(pstParent, pstRoot);
                pstNode = pstRoot;
                break;
            }
        }
    }

    if (pstNode)
    {
        pstNode->enColor = BLACK;
    } 

    return pstRoot;
}