一個有趣的技術,有時也適用於這個問題(並不總是不過,因爲你會看到),是利用數組「週期」,每個週期存儲一組。週期存儲爲一堆「下一個元素」鏈接,因此next[i]
將給出一個表示下一個項目的整數。最後,鏈接迴環,所以這些集合必然是不相交的。
有一件好事就是你可以通過交換兩件物品來將兩件套結合在一起。
int temp = next[s1];
next[s1] = next[s2];
next[s2] = temp;
:如果你有指標s1
和s2
,那麼他們在(s1
和s2
不是特別代表,你可以參考的一組任意元素)的集合可以通過交換那些位置是被聯合或者,您可以交換您的語言。據我所知,Java並沒有很好的std::swap(&next[s1], &next[s2])
。
這顯然與循環鏈表有關,但更緊湊。缺點是你必須提前準備你的「宇宙」。通過鏈接列表,您可以任意添加項目。另外,如果你的物品不是0到n的整數,那麼你將有一個陣列來完成映射,但這不是一個純粹的缺點或上升,這取決於你需要做什麼。
一個好處是,因爲你可以通過索引來引用一個項目,所以它更容易與其他數據結構結合在一起,例如它喜歡與Union Find結構(它也是一個整數數組,其中兩個),繼承兩個結構提供的O(1)聯合,保留聯合查找的攤銷O(α(n))查找,以及(從循環結構)保持O(m)集枚舉一套大小爲m。所以你大多都是兩全其美的。
在情況下,它是不是很明顯,可以用「所有singleton」像這樣初始化「宇宙」:
for (int i = 0; i < next.length; i++)
next[i] = i;
一樣聯盟查找。
「最好」在哪方面?還有哪些其他操作需要?只需支持工會就可以在O(1)中輕鬆完成。 – Henry
您需要說明套件應該支持的其他操作。例如,沒有固定的時間聯合,對於應該實現java.util.Set的集合。如果有人想要長時間工會,他們通常會指導你使用union-find算法(谷歌),但這與實現普通的Set接口有很大不同。 –