示例#1
0
        /// <summary>
        /// Modifies this data structure to also contains all unions from other.
        /// </summary>
        /// <param name="other"></param>
        /// <returns>Whether this object was changed</returns>
        public bool CopyUnions(DisjointSets <T> other)
        {
            // Create a temporary reverse mapping of other's items to its entries - O(n)
            var otherItemsToEntries = new Dictionary <DisjointSetItem, T>();

            foreach (var kvp in other.entriesToItems)
            {
                otherItemsToEntries[kvp.Value] = kvp.Key;
            }

            // Unite each of other's entries with its representative only - O(n)
            bool ret = false;

            foreach (var entryAndSetItem in other.entriesToItems)
            {
                var entry = entryAndSetItem.Key;
                var item  = entryAndSetItem.Value;
                if (item.IsSingle() == true)
                {
                    continue;
                }
                other.Find(item);
                var  repEntry         = otherItemsToEntries[item.parent];
                bool wasOnlyUnitedNow = this.Union(entry, repEntry);
                ret = ret || wasOnlyUnitedNow;
            }
            return(ret);
        }
示例#2
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.
                    }
                }
            }
        }