示例#1
0
 /// <summary>
 /// Tests whether the given value is a member of the <see cref="DisjointSet"/>.
 /// </summary>
 /// <param name="left">The <see cref="DisjointSet"/> to examine.</param>
 /// <param name="right">The value to test for membership.</param>
 /// <returns>
 /// <c>true</c> if the value is contained in any <see cref="Range"/>
 /// of the <see cref="DisjointSet"/>.
 /// </returns>
 public static bool Contains(ref DisjointSet left, ulong right)
 {
     return((left == null) ? false : (left = Splay(left.Find(right))).Value & right);
 }
示例#2
0
        private DisjointSet Insert(Range value)
        {
            checked {
                for (DisjointSet p = this, q; ; p = q)
                {
                    // If the new range is strictly less than or greater than the
                    // existing range and is not *adjacent*, descend down the left
                    // or right subtree like a normal binary-tree search.  If there
                    // is no appropriate subtree, insert a brand new node.
                    if (value.Max < p.Value.Min - (p.Value.Min > ulong.MinValue ? 1ul : 0ul))
                    {
                        q = p.Left;
                        if (q == null)
                        {
                            p.Left        = new DisjointSet(null, value, null);
                            p.Left.Parent = p;
                            return(p.Left);
                        }
                    }
                    else if (value.Min > p.Value.Max + (p.Value.Max < ulong.MaxValue ? 1ul : 0ul))
                    {
                        q = p.Right;
                        if (q == null)
                        {
                            p.Right        = new DisjointSet(null, value, null);
                            p.Right.Parent = p;
                            return(p.Right);
                        }
                    }

                    // But if the ranges overlap or are adjacent, we've found our mark.
                    else
                    {
                        // Get the left and right subtrees.
                        DisjointSet left = p.Left, right = p.Right;

                        // Eliminate all subtrees that overlap or are adjacent to the new range.
                        // Detach the subtrees so we can splay them.
                        // Splay each subtree so the value for comparison will be at the top.
                        // Each time, adjust the new range if the existing ranges extend the bounds.
                        if (left != null)
                        {
                            do
                            {
                                DisjointSet parent = left.Parent;
                                left.Parent = null;
                                left        = Splay(left.Find(value.Min));
                                left.Parent = Parent;
                                if (value.Min <= left.Value.Max + (left.Value.Max < ulong.MaxValue ? 1ul : 0ul))
                                {
                                    value = new Range(Math.Min(value.Min, left.Value.Min), value.Max);
                                    left  = left.Left;
                                }
                                else
                                {
                                    break;
                                }
                            } while (left != null);
                        }
                        if (right != null)
                        {
                            do
                            {
                                DisjointSet parent = right.Parent;
                                right.Parent = null;
                                right        = Splay(right.Find(value.Max));
                                right.Parent = parent;
                                if (right.Value.Min - (right.Value.Min > ulong.MinValue ? 1ul : 0ul) <= value.Max)
                                {
                                    value = new Range(value.Min, Math.Max(value.Max, right.Value.Max));
                                    right = right.Right;
                                }
                                else
                                {
                                    break;
                                }
                            } while (right != null);
                        }

                        // Now extend the bounds of the range at the root of the tree.
                        p.Value = new Range(Math.Min(value.Min, p.Value.Min), Math.Max(value.Max, p.Value.Max));

                        // Reattach the eliminated subtrees' branches, which are now not adjacent to the new value.
                        p.Left  = left;
                        p.Right = right;

                        // Reattach their parents.
                        if (left != null)
                        {
                            left.Parent = p;
                            left.AssertWellOrdered();
                        }
                        if (right != null)
                        {
                            right.Parent = p;
                            right.AssertWellOrdered();
                        }

                        // Return the "inserted" node.
                        p.AssertWellOrdered();
                        return(p);
                    }
                }
            }
        }
示例#3
0
 /// <summary>
 /// Tests whether the given value is a member of the <see cref="DisjointSet"/>.
 /// </summary>
 /// <param name="left">The <see cref="DisjointSet"/> to examine.</param>
 /// <param name="right">The value to test for membership.</param>
 /// <returns>
 /// <c>true</c> if the value is contained in any <see cref="Range"/>
 /// of the <see cref="DisjointSet"/>.
 /// </returns>
 public static bool Contains(ref DisjointSet left, ulong right)
 {
     return (left == null) ? false : (left = Splay(left.Find(right))).Value & right;
 }