public static BalancedBoundingNode Search(BalancedBoundingNode node, TBounds key)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            while (!ReferenceEquals(node, Nil) && !(key.CompareTo(node.LowerBound) >= 0 && key.CompareTo(node.UpperBound) < 0))
            {
                if (key.CompareTo(node.LowerBound) < 0)
                {
                    node = node.LowerTree;
                }
                else
                {
                    if (ReferenceEquals(node.UpperTree, Nil) && (node.UpperBound.CompareTo(key) == 0))
                    {
                        return(node);
                    }
                    node = node.UpperTree;
                }
            }

            return(node);
        }
        public BalancedBoundingNode Insert(TBounds lower, TBounds upper, TPayload value)
        {
            var node = new BalancedBoundingNode(lower, upper, value, BalancedBoundingNode.Colour.Black);

            Insert(node);
            return(node);
        }
        public void RightRotate(BalancedBoundingNode y)
        {
            BalancedBoundingNode x = y.LowerTree;

            y.LowerTree = x.UpperTree; // y lower is undefined not so set that
            if (x.UpperTree != Nil)    // if the node that is being assigned is nto nil then set its parent also.
            {
                x.UpperTree.Parent = y;
            }

            x.Parent = y.Parent; // setup the parent of new root.
            if (y.Parent == Nil) // if the parent was nil then we know that it is the root node of the tree.
            {
                this.Root = x;
            }
            else if (y == y.Parent.LowerTree) // otherwise we need to fix up based on whatever side of the parent node y sits on
            {
                y.Parent.LowerTree = x;
            }
            else
            {
                y.Parent.UpperTree = x;
            }

            x.UpperTree = y;
            y.Parent    = x;
        }
        public void LeftRotate(BalancedBoundingNode x)
        {
            BalancedBoundingNode y = x.UpperTree;   // set y

            x.UpperTree = y.LowerTree;              // y used to take this position so safe to write to.
            // now y.lower can be set.
            if (!ReferenceEquals(y.LowerTree, Nil)) // hook up the parent
            {
                y.LowerTree.Parent = x;
            }

            y.Parent = x.Parent;                // x's old parent is now y parent (eg at the root node Nil)

            if (ReferenceEquals(x.Parent, Nil)) // so we need to figure out if x was root node, if so tree needs to know y is new root.
            {
                this.Root = y;
            }
            else if (ReferenceEquals(x, x.Parent.LowerTree)) // otherwise we need to figure out if x was lower or upper of its parent.
            {
                x.Parent.LowerTree = y;
            }
            else
            {
                x.Parent.UpperTree = y;
            }

            y.LowerTree = x;
            x.Parent    = y;
        }
 static BalancedBoundingTree()
 {
     Nil           = new BalancedBoundingNode(default(TBounds), default(TBounds), default(TPayload), BalancedBoundingNode.Colour.Black);
     Nil.LowerTree = Nil;
     Nil.UpperTree = Nil;
     Nil.Parent    = Nil;
 }
 public void FixupNode(BalancedBoundingNode node)
 {
     while (node.Parent.NodeColour == BalancedBoundingNode.Colour.Red)
     {
         if (node.Parent == node.Parent.Parent.LowerTree)
         {
             var y = node.Parent.Parent.UpperTree;
             if (y.NodeColour == BalancedBoundingNode.Colour.Red)
             {
                 node.Parent.NodeColour        = BalancedBoundingNode.Colour.Black;
                 y.NodeColour                  = BalancedBoundingNode.Colour.Black;
                 node.Parent.Parent.NodeColour = BalancedBoundingNode.Colour.Red;
                 node = node.Parent.Parent;
             }
             else
             {
                 if (node == node.Parent.UpperTree)
                 {
                     node = node.Parent;
                     LeftRotate(node);
                 }
                 node.Parent.NodeColour        = BalancedBoundingNode.Colour.Black;
                 node.Parent.Parent.NodeColour = BalancedBoundingNode.Colour.Red;
                 RightRotate(node.Parent.Parent);
             }
         }
         else
         {
             var y = node.Parent.Parent.LowerTree;
             if (y.NodeColour == BalancedBoundingNode.Colour.Red)
             {
                 node.Parent.NodeColour        = BalancedBoundingNode.Colour.Black;
                 y.NodeColour                  = BalancedBoundingNode.Colour.Black;
                 node.Parent.Parent.NodeColour = BalancedBoundingNode.Colour.Red;
                 node = node.Parent.Parent;
             }
             else
             {
                 if (node == node.Parent.LowerTree)
                 {
                     node = node.Parent;
                     RightRotate(node);
                 }
                 node.Parent.NodeColour        = BalancedBoundingNode.Colour.Black;
                 node.Parent.Parent.NodeColour = BalancedBoundingNode.Colour.Red;
                 LeftRotate(node.Parent.Parent);
             }
         }
     }
     Root.NodeColour = BalancedBoundingNode.Colour.Black;
 }
        public void Insert(BalancedBoundingNode node)
        {
            BalancedBoundingNode y = Nil;
            BalancedBoundingNode x = Root;

            // find the parent of the node
            while (x != Nil)
            {
                y = x;
                if (node.CompareTo(x) < 0)
                {
                    x = x.LowerTree;
                }
                else
                {
                    x = x.UpperTree;
                }
            }
            node.Parent = y;

            if (y == Nil)
            {
                Root = node;
            }
            else if (node.CompareTo(y) < 0)
            {
                y.LowerTree = node;
            }
            else
            {
                y.UpperTree = node;
            }

            node.LowerTree  = Nil;
            node.UpperTree  = Nil;
            node.NodeColour = BalancedBoundingNode.Colour.Red;
            FixupNode(node);
        }
 public BalancedBoundingTree(TBounds lower, TBounds upper, TPayload value)
 {
     Root = new BalancedBoundingNode(lower, upper, value, BalancedBoundingNode.Colour.Black);
 }