コード例 #1
0
 /// <summary>
 /// Finds the representative of the item's set
 /// </summary>
 /// <param name="x"></param>
 /// <returns></returns>
 protected DisjointSetItem Find(DisjointSetItem x)
 {
     if (x.parent != x)
     {
         x.parent = Find(x.parent);
     }
     return(x.parent);
 }
コード例 #2
0
 /// <summary>
 /// Initially all entries are single item sets.
 /// </summary>
 /// <param name="entries"></param>
 public DisjointSets(ISet <T> entries)
 {
     entriesToItems = new Dictionary <T, DisjointSetItem>();
     maxRank        = 0;
     foreach (var entry in entries)
     {
         entriesToItems[entry] = new DisjointSetItem();
     }
 }
コード例 #3
0
 /// <summary>
 /// Does nothing if entry is already present.
 /// Returns whether the entry was really added now.
 /// </summary>
 public bool AddSet(T entry)
 {
     if (entriesToItems.ContainsKey(entry) == false)
     {
         entriesToItems[entry] = new DisjointSetItem();
         return(true);
     }
     return(false);
 }
コード例 #4
0
        public DisjointSets(DisjointSets <T> other)
        {
            entriesToItems = new Dictionary <T, DisjointSetItem>();
            maxRank        = other.maxRank;
            var queue = new Queue <T>(other.entriesToItems.Keys);
            var otherRepsToNewReps = new Dictionary <DisjointSetItem, DisjointSetItem>();

            while (queue.Count != 0)
            {
                var entry = queue.Dequeue();
                var item  = other.entriesToItems[entry];
                other.Find(item);        // Makes item.parent point directly do the set's representative
                if (item.parent == item) // This is the set's representative
                {
                    var newItem = new DisjointSetItem();
                    entriesToItems[entry] = newItem;
                    // .parent already points to itself as needed
                    newItem.rank = item.rank; // Since all items in a set do not point directly to the set's rep,
                                              // the set's rank would have been 1 regardless of its size, had it
                                              // been created by calls to Union. We prefer to remember the original rank.
                    otherRepsToNewReps[item] = newItem;
                }
                else
                {
                    if (otherRepsToNewReps.ContainsKey(item.parent)) // We've copied this rep already
                    {
                        var newItem = new DisjointSetItem();
                        entriesToItems[entry] = newItem;
                        newItem.parent        = otherRepsToNewReps[item.parent];
                        // .rank not important in non-rep items
                    }
                    else
                    {
                        queue.Enqueue(entry); // Wait for the rep to be copied first.
                    }
                }
            }
        }
コード例 #5
0
 public DisjointSetItem()
 {
     parent = this;
     rank   = 0;
 }