Example #1
0
        private void RebalancePostDeletion(RBTreeNode node)
        {
            // Very similar to RebalancePostInsertion function
            // node is the node in the location of/closest to the node just deleted
            RBTreeNode s; // represents sibbling of node

            while (node != Root && node.IsBlack())
            {
                if (node == node.Parent().Left())
                {
                    s = node.Parent().Right();

                    if (s.IsRed())   // case 1
                    {
                        s.SetBlack();
                        node.Parent().SetRed();
                        RotateLeft(node.Parent());
                        s = node.Parent().Right();
                    }

                    if (s.Left().IsBlack() && s.Right().IsBlack())   // case 2
                    {
                        s.SetRed();
                        node = node.Parent();
                    }
                    else
                    {
                        if (s.Right().IsBlack())   // case 3
                        {
                            s.Left().SetBlack();
                            s.SetRed();
                            RotateRight(s);
                            s = node.Parent().Right();
                        }

                        if (s.Parent().IsRed())
                        {
                            s.SetRed();
                        }
                        else
                        {
                            s.SetBlack();
                        }

                        node.Parent().SetBlack();
                        s.Right().SetBlack();
                        RotateLeft(s.Parent());
                        node = Root;
                    }
                }
                else
                {
                    s = node.Parent().Left();

                    if (s.IsRed())
                    {
                        s.SetBlack();
                        node.Parent().SetRed();
                        RotateRight(node.Parent());
                        s = node.Parent().Left();
                    }
                    if (s.Right() == null)
                    {
                        s.SetRight(Leaf);
                    }
                    if (s.Left() == null)
                    {
                        s.SetLeft(Leaf);
                    }
                    if (s.Right().IsBlack() && s.Left().IsBlack())
                    {
                        s.SetRed();
                        node = node.Parent();
                    }
                    else
                    {
                        if (s.Left().IsBlack())
                        {
                            s.Right().SetBlack();
                            s.SetRed();
                            RotateLeft(s);
                            s = node.Parent().Left();
                        }

                        if (s.Parent().IsRed())
                        {
                            s.SetRed();
                        }
                        else
                        {
                            s.SetBlack();
                        }

                        node.Parent().SetBlack();
                        s.Left().SetBlack();
                        RotateRight(node.Parent());
                        node = Root;
                    }
                }
            }
            node.SetBlack();
        }