예제 #1
0
파일: RBTree.cs 프로젝트: SamarSamir9/dcel
        private void Rotate(TNode node, RBTreeDirection direction)
        {
            RBTreeDirection oppositeDirection = OppositeDirection(direction);

            //replacement will rotate to where node was, pushing node down
            TNode replacement = node.GetChild(oppositeDirection);

            node.SetChild(replacement.GetChild(direction), oppositeDirection);

            if (replacement.GetChild(direction) != SentinelNode)
            {
                replacement.GetChild(direction).parent = node;
            }

            if (replacement != SentinelNode)
            {
                replacement.parent = node.parent;
            }

            if (node.HasParent)
            {
                node.parent.SetChild(replacement, node.ChildDirection);
            }
            else
            {
                Root = replacement;
            }

            replacement.SetChild(node, direction);
            if (node != SentinelNode)
            {
                node.parent = replacement;
            }
        }
예제 #2
0
파일: RBTree.cs 프로젝트: SamarSamir9/dcel
        /// <summary>
        /// Enumerate the nodes in the tree.
        /// </summary>
        public IEnumerable <TNode> GetNodes(bool ascending)
        {
            RBTreeDirection direction = (ascending ? RBTreeDirection.Right : RBTreeDirection.Left);

            for (TNode node = SentinelNode.GetNeighbor(direction); node != SentinelNode; node = node.GetNeighbor(direction))
            {
                yield return(node);
            }
        }
예제 #3
0
파일: RBTree.cs 프로젝트: SamarSamir9/dcel
 internal void SetChild(TNode child, RBTreeDirection direction)
 {
     if (direction == RBTreeDirection.Left)
     {
         left = child;
     }
     else
     {
         right = child;
     }
 }
예제 #4
0
파일: RBTree.cs 프로젝트: SamarSamir9/dcel
        private void RestorePropertiesAfterRemove(TNode node)
        {
            while (node != Root && node.color == RBTreeNodeColor.Black)
            {
                RBTreeDirection direction         = node.ChildDirection;
                RBTreeDirection oppositeDirection = OppositeDirection(direction);

                TNode sibling = node.Sibling;
                if (sibling.color == RBTreeNodeColor.Red)
                {
                    sibling.color     = RBTreeNodeColor.Black;
                    node.parent.color = RBTreeNodeColor.Red;
                    Rotate(node.parent, direction);
                    sibling = node.parent.GetChild(oppositeDirection);
                }

                if ((sibling.left.color == RBTreeNodeColor.Black) &&
                    (sibling.right.color == RBTreeNodeColor.Black))
                {
                    sibling.color = RBTreeNodeColor.Red;
                    node          = node.parent;
                }
                else
                {
                    if (sibling.GetChild(oppositeDirection).color == RBTreeNodeColor.Black)
                    {
                        sibling.GetChild(direction).color = RBTreeNodeColor.Black;
                        sibling.color = RBTreeNodeColor.Red;
                        Rotate(sibling, oppositeDirection);
                        sibling = node.parent.GetChild(oppositeDirection);
                    }

                    sibling.color     = node.parent.color;
                    node.parent.color = RBTreeNodeColor.Black;
                    sibling.GetChild(oppositeDirection).color = RBTreeNodeColor.Black;
                    Rotate(node.parent, direction);
                    node = Root;
                }
            }

            node.color = RBTreeNodeColor.Black;
        }
예제 #5
0
파일: RBTree.cs 프로젝트: SamarSamir9/dcel
        private TNode FindExtremum(Predicate <TKey> predicate, RBTreeDirection direction)
        {
            RBTreeDirection oppositeDirection = OppositeDirection(direction);

            TNode extremum = null;
            TNode node     = Root;

            while (node != SentinelNode)
            {
                if (predicate(node.Key))
                {
                    extremum = node;
                    node     = node.GetChild(direction);
                }
                else
                {
                    node = node.GetChild(oppositeDirection);
                }
            }
            return(extremum);
        }
예제 #6
0
파일: RBTree.cs 프로젝트: SamarSamir9/dcel
 private TNode TraverseToFindNeighbor(TNode node, RBTreeDirection direction)
 {
     if (node.GetChild(direction) == SentinelNode)
     {
         while (node.HasParent && node.ChildDirection == direction)
         {
             node = node.parent;
         }
         return(node.HasParent ? node.parent : SentinelNode);
     }
     else
     {
         node = node.GetChild(direction);
         RBTreeDirection oppositeDirection = OppositeDirection(direction);
         while (node.GetChild(oppositeDirection) != SentinelNode)
         {
             node = node.GetChild(oppositeDirection);
         }
         return(node);
     }
 }
예제 #7
0
파일: RBTree.cs 프로젝트: SamarSamir9/dcel
        private void RestorePropertiesAfterAdd(TNode node)
        {
            while (node != Root && node.parent.color == RBTreeNodeColor.Red)
            {
                TNode uncle = node.parent.Sibling;
                if (uncle != null && uncle.color == RBTreeNodeColor.Red)
                {
                    TNode parent      = node.parent;
                    TNode grandparent = parent.parent;

                    grandparent.color = RBTreeNodeColor.Red;
                    parent.color      = RBTreeNodeColor.Black;
                    uncle.color       = RBTreeNodeColor.Black;

                    node = grandparent;
                }
                else
                {
                    RBTreeDirection grandparentToParent = node.parent.ChildDirection;
                    RBTreeDirection parentToNode        = node.ChildDirection;
                    if (grandparentToParent != parentToNode)
                    {
                        node = node.parent;
                        Rotate(node, grandparentToParent);
                    }

                    TNode parent      = node.parent;
                    TNode grandparent = parent.parent;

                    grandparent.color = RBTreeNodeColor.Red;
                    parent.color      = RBTreeNodeColor.Black;
                    Rotate(grandparent, OppositeDirection(grandparentToParent));
                }
            }

            Root.color = RBTreeNodeColor.Black;
        }
예제 #8
0
파일: RBTree.cs 프로젝트: SamarSamir9/dcel
        private TNode FindRangeExtremum(KeyRangePredicate rangePredicate, RBTreeDirection direction)
        {
            TNode extremum = null;
            TNode node     = Root;

            while (node != SentinelNode)
            {
                int result = rangePredicate(node.Key);
                if (result == 0)
                {
                    extremum = node;
                    node     = node.GetChild(direction);
                }
                else if (result < 0)
                {
                    node = node.right;
                }
                else
                {
                    node = node.left;
                }
            }
            return(extremum);
        }
예제 #9
0
파일: RBTree.cs 프로젝트: SamarSamir9/dcel
 internal TNode GetChild(RBTreeDirection direction)
 {
     return(direction == RBTreeDirection.Left ? left : right);
 }
예제 #10
0
파일: RBTree.cs 프로젝트: SamarSamir9/dcel
 internal TNode GetNeighbor(RBTreeDirection direction)
 {
     return(direction == RBTreeDirection.Left ? predecessor : successor);
 }
예제 #11
0
파일: RBTree.cs 프로젝트: SamarSamir9/dcel
 private static RBTreeDirection OppositeDirection(RBTreeDirection dir)
 {
     return(dir == RBTreeDirection.Left ? RBTreeDirection.Right : RBTreeDirection.Left);
 }