예제 #1
0
        private void DeleteCase1(IRbNode n)
        {
            if (n.Parent == null)
                return;

            DeleteCase2(n);
        }
예제 #2
0
        //-----------------------------------
        private void InsertCase2(IRbNode n)
        {
            if (NodeColor(n.Parent) == Color.Black)
                return; // Tree is still valid

            InsertCase3(n);
        }
예제 #3
0
        public void Delete(IRbNode template, out IRbNode deletedAlt)
        {
            deletedAlt = null;
            var n = LookupNode(template);

            if (n == null)
            {
                return; // Key not found, do nothing
            }
            if (n.Left != null && n.Right != null)
            {
                // Copy key/value from predecessor and then delete it instead
                var pred = MaximumNode(n.Left);
                pred.AssignValueTo(n);
                n          = pred;
                deletedAlt = pred;
            }

            //assert n.left == null || n.right == null;
            var child = n.Right ?? n.Left;

            if (NodeColor(n) == Color.Black)
            {
                n.Color = NodeColor(child);
                DeleteCase1(n);
            }

            ReplaceNode(n, child);

            if (NodeColor(Root) == Color.Red)
            {
                Root.Color = Color.Black;
            }
        }
예제 #4
0
        private static void PrintHelper(IRbNode n, int indent)
        {
            if (n == null)
            {
                Trace.WriteLine("<empty tree>");
                return;
            }

            if (n.Left != null)
            {
                PrintHelper(n.Left, indent + _indentStep);
            }

            for (var i = 0; i < indent; i++)
            {
                Trace.Write(" ");
            }
            if (n.Color == Color.Black)
            {
                Trace.WriteLine(" " + n + " ");
            }
            else
            {
                Trace.WriteLine("<" + n + ">");
            }

            if (n.Right != null)
            {
                PrintHelper(n.Right, indent + _indentStep);
            }
        }
예제 #5
0
 //------------------------------------
 private void InsertCase1(IRbNode n)
 {
     if (n.Parent == null)
         n.Color = Color.Black;
     else
         InsertCase2(n);
 }
예제 #6
0
 internal void FireNodeOperation(IRbNode node, NodeOperation operation)
 {
     if (NodeOperation != null)
     {
         NodeOperation(node, operation);
     }
 }
예제 #7
0
        private static IRbNode MaximumNode(IRbNode n)
        {
            //assert n != null;
            while (n.Right != null)
            {
                n = n.Right;
            }

            return(n);
        }
예제 #8
0
        private static void VerifyProperty1(IRbNode n)
        {
            Assert.IsTrue(NodeColor(n) == Color.Red || NodeColor(n) == Color.Black);

            if (n == null)
            {
                return;
            }
            VerifyProperty1(n.Left);
            VerifyProperty1(n.Right);
        }
예제 #9
0
        public bool TryLookup(IRbNode template, out IRbNode val)
        {
            var n = LookupNode(template);

            if (n == null)
            {
                val = null;
                return(false);
            }
            val = n;
            return(true);
        }
예제 #10
0
        public void Insert(IRbNode newNode)
        {
            newNode.Color = Color.Red;

            var insertedNode = newNode;

            if (Root == null)
            {
                Root = insertedNode;
            }
            else
            {
                var n = Root;

                while (true)
                {
                    var compResult = newNode.CompareTo(n);

                    if (compResult == 0)
                    {
                        throw new RbTreeDuplicatedItemException(
                            "RBNode " + newNode + " already present in tree");
                    }

                    if (compResult < 0)
                    {
                        if (n.Left == null)
                        {
                            n.Left = insertedNode;

                            break;
                        }
                        n = n.Left;
                    }
                    else
                    {
                        //assert compResult > 0;
                        if (n.Right == null)
                        {
                            n.Right = insertedNode;

                            break;
                        }
                        n = n.Right;
                    }
                }

                insertedNode.Parent = n;
            }

            InsertCase1(insertedNode);
            NodeInserted?.Invoke(insertedNode);
        }
예제 #11
0
 private void DeleteCase4(IRbNode n)
 {
     if (NodeColor(n.Parent) == Color.Red &&
         NodeColor(n.Sibling()) == Color.Black &&
         NodeColor(n.Sibling().Left) == Color.Black &&
         NodeColor(n.Sibling().Right) == Color.Black)
     {
         n.Sibling().Color = Color.Red;
         n.Parent.Color = Color.Black;
     }
     else
         DeleteCase5(n);
 }
예제 #12
0
        private void RotateLeft(IRbNode n)
        {
            var r = n.Right;

            ReplaceNode(n, r);
            n.Right = r.Left;
            if (r.Left != null)
            {
                r.Left.Parent = n;
            }
            r.Left   = n;
            n.Parent = r;
        }
예제 #13
0
 //----------------------------
 private void InsertCase3(IRbNode n)
 {
     if (NodeColor(n.Uncle()) == Color.Red)
     {
         n.Parent.Color = Color.Black;
         n.Uncle().Color       = Color.Black;
         n.Grandparent().Color = Color.Red;
         InsertCase1(n.Grandparent());
     }
     else
     {
         InsertCase4(n);
     }
 }
예제 #14
0
        private static void DoVisitTreeNodes(Action <IRbNode> action, IRbNode walker)
        {
            if (walker.Left != null)
            {
                DoVisitTreeNodes(action, walker.Left);
            }

            action?.Invoke(walker);

            if (walker.Right != null)
            {
                DoVisitTreeNodes(action, walker.Right);
            }
        }
예제 #15
0
 //----------------------------
 private void InsertCase5(IRbNode n)
 {
     n.Parent.Color = Color.Black;
     n.Grandparent().Color = Color.Red;
     if (Equals(n, n.Parent.Left) && Equals(n.Parent, n.Grandparent().Left))
     {
         RotateRight(n.Grandparent());
     }
     else
     {
         //assert n == n.parent.right && n.parent == n.grandparent().right;
         RotateLeft(n.Grandparent());
     }
 }
예제 #16
0
 private void DeleteCase3(IRbNode n)
 {
     if (NodeColor(n.Parent) == Color.Black &&
         NodeColor(n.Sibling()) == Color.Black &&
         NodeColor(n.Sibling().Left) == Color.Black &&
         NodeColor(n.Sibling().Right) == Color.Black)
     {
         n.Sibling().Color = Color.Red;
         DeleteCase1(n.Parent);
     }
     else
     {
         DeleteCase4(n);
     }
 }
예제 #17
0
        private void RotateRight(IRbNode n)
        {
            var l = n.Left;

            ReplaceNode(n, l);
            n.Left = l.Right;

            if (l.Right != null)
            {
                l.Right.Parent = n;
            }

            l.Right  = n;
            n.Parent = l;
        }
예제 #18
0
        //----------------------------
        private void InsertCase4(IRbNode n)
        {
            if (Equals(n, n.Parent.Right) && Equals(n.Parent, n.Grandparent().Left))
            {
                RotateLeft(n.Parent);
                n = n.Left;
            }
            else if (Equals(n, n.Parent.Left) && Equals(n.Parent, n.Grandparent().Right))
            {
                RotateRight(n.Parent);
                n = n.Right;
            }

            InsertCase5(n);
        }
예제 #19
0
        private void DeleteCase2(IRbNode n)
        {
            if (NodeColor(n.Sibling()) == Color.Red)
            {
                n.Parent.Color = Color.Red;
                n.Sibling().Color = Color.Black;

                if (Equals(n, n.Parent.Left))
                    RotateLeft(n.Parent);
                else
                    RotateRight(n.Parent);
            }

            DeleteCase3(n);
        }
예제 #20
0
        private static void VerifyProperty4(IRbNode n)
        {
            if (NodeColor(n) == Color.Red)
            {
                Assert.IsTrue((NodeColor(n.Left) == Color.Black));
                Assert.IsTrue((NodeColor(n.Right) == Color.Black));
                Assert.IsTrue((NodeColor(n.Parent) == Color.Black));
            }

            if (n == null)
            {
                return;
            }
            VerifyProperty4(n.Left);
            VerifyProperty4(n.Right);
        }
예제 #21
0
        private IRbNode LookupNode(IRbNode template)
        {
            var n = Root;

            while (n != null)
            {
                var compResult = template.CompareTo(n);

                if (compResult == 0)
                {
                    return(n);
                }
                n = compResult < 0 ? n.Left : n.Right;
            }

            return(null);
        }
예제 #22
0
 private void DeleteCase6(IRbNode n)
 {
     n.Sibling().Color = NodeColor(n.Parent);
     n.Parent.Color = Color.Black;
     if (Equals(n, n.Parent.Left))
     {
         //assert nodeColor(n.sibling().right) == Color.RED;
         n.Sibling().Right.Color = Color.Black;
         RotateLeft(n.Parent);
     }
     else
     {
         //assert nodeColor(n.sibling().left) == Color.RED;
         n.Sibling().Left.Color = Color.Black;
         RotateRight(n.Parent);
     }
 }
예제 #23
0
        private void ReplaceNode(IRbNode oldn, IRbNode newn)
        {
            if (oldn.Parent == null)
            {
                Root = newn;
            }
            else
            {
                if (Equals(oldn, oldn.Parent.Left))
                    oldn.Parent.Left = newn;
                else
                    oldn.Parent.Right = newn;
            }

            if (newn != null)
            {
                newn.Parent = oldn.Parent;
            }
        }
예제 #24
0
        private void DeleteCase5(IRbNode n)
        {
            if (Equals(n, n.Parent.Left) &&
                NodeColor(n.Sibling()) == Color.Black &&
                NodeColor(n.Sibling().Left) == Color.Red &&
                NodeColor(n.Sibling().Right) == Color.Black)
            {
                n.Sibling().Color = Color.Red;
                n.Sibling().Left.Color = Color.Black;
                RotateRight(n.Sibling());
            }
            else if (Equals(n, n.Parent.Right) &&
                     NodeColor(n.Sibling()) == Color.Black &&
                     NodeColor(n.Sibling().Right) == Color.Red &&
                     NodeColor(n.Sibling().Left) == Color.Black)
            {
                n.Sibling().Color = Color.Red;
                n.Sibling().Right.Color = Color.Black;
                RotateLeft(n.Sibling());
            }

            DeleteCase6(n);
        }
예제 #25
0
        private static int VerifyProperty5Helper(IRbNode n, int blackCount, int pathBlackCount)
        {
            if (NodeColor(n) == Color.Black)
            {
                blackCount++;
            }
            if (n == null)
            {
                if (pathBlackCount == -1)
                {
                    pathBlackCount = blackCount;
                }
                else
                {
                    Assert.IsTrue(blackCount == pathBlackCount);
                }
                return(pathBlackCount);
            }

            pathBlackCount = VerifyProperty5Helper(n.Left, blackCount, pathBlackCount);
            pathBlackCount = VerifyProperty5Helper(n.Right, blackCount, pathBlackCount);

            return(pathBlackCount);
        }
예제 #26
0
 private static void VerifyProperty5(IRbNode root)
 {
     VerifyProperty5Helper(root, 0, -1);
 }
예제 #27
0
 private static Color NodeColor(IRbNode n)
 {
     return(n == null ? Color.Black : n.Color);
 }
예제 #28
0
 private static void VerifyProperty2(IRbNode root)
 {
     Assert.IsTrue(NodeColor(root) == Color.Black);
 }
예제 #29
0
 public RbTree(IRbNode root)
 {
     Root = root;
 }