/// <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); }
/// <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(); } }
/// <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); }
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. } } } }
public DisjointSetItem() { parent = this; rank = 0; }