Her küme, diğer kümelerin var olduğu bir kaydı tutarsa ve toplamda kümeniz varsa, bir koleksiyon için herhangi bir veri yapısını ( örn. İkili arama ağaçları, vb. ) Alınabilecek bir yapıya kolayca dönüştürebilirsiniz . zamanında iki kümenin kesişme unsuru .s>0O(logs)
Her set, tamamen sipariş edilen bazı setlerden benzersiz bir tanımlayıcıya sahip olmalıdır. açıkça tanımlayıcı yalnızca dizin olabilir.S1,S2,…
Kümelerin "kayıt defterini" uygulamalısınız; tanımladığınız tüm setlerin bir koleksiyonunu tutan bir veri yapısı. Kayıt defteri, kolay erişim ( örneğin , grubu silmek istiyorsanız) ve kümelerin doğrusal zamanlı geçişini sağlamak için bir arama ağacı veri yapısı olarak uygulanmalıdır .
Her küme , diğer kümelerin her birinin bir "dizinini" tutar - bunların bir kopyası değil, diğer kümelerin etiketleri tarafından endekslenen bir veri yapısı. Bu dizin, her kümesi için , öğelerinin tümünün ikili arama ağacını korumak için kullanılır . (İki grup ve bu arama ağacının bir kopyasını paylaşır.)S k S j ∩ S k S j S kSjSkSj∩SkSjSk
Başlatma
Bir dizi başlatma içeren gruptan seçilmektedir elemanları ağacı başlatmak için işlemleri, (kayıt kopyalama) işlemleri Eğer başlatma olarak grubu endeksi , ve diğer setlerin her birinin indekslerine eklemek için kayıt defteri boyunca . Endeksinde , biz temsil arama ağaçlar oluşturmak diğer setleri için ; indeksi için aynı işaretçiyi .O ( 1 ) O ( sT=∅O(1)T O ( s günlük ler ) , T S j T T ∩ S j = ∅ S j S jO(s)TO(slogs)TSjTT∩Sj=∅SjSj
Küme bir eleman eklemeT
Bazı ekleme kümesine zamanı alır , burada, her zamanki gibi. Ayrıca , zamanını alan diğer kümelerinin her birinde üyeliğini test ediyoruz. buradaevrenin (veya en büyük kümesinin) ve , kayıt defterindeki kümelerin sayısıdır. Her bir grup için şekilde , aynı zamanda uç kümesi için dizin içine . Bu tür her set içinT O ( log n T ) n T = | T | x S 1 , S 2 , … O ( log n S 1 + log n S 2 + ⋯ ) ⊆ O ( s log n ) , n = | V | S j s S j x ∈ S jx∈VTO(lognT)nT=|T|xS1,S2,…
O(lognS1+lognS2+⋯)⊆O(slogn),
n=|V|SjsSjx∈SjxSj∩TSjBu alır aramak için, zaman indeksindeki ve eklemek için olarak ; tüm setlerde bu zaman alır . kümelerinin sayısının evreninin boyutundan çok daha az olduğunu (yani, varsayalım ), eleman ekleme için toplam süre .
O(logs+lognT)SjTxSj∩TS1,S2,…O(slogs+slognT)SjVs≪nO(slogn)
Kümelerde yinelemelere izin vermezseniz , üyelik testini ve diğer kümeler için eklemeleri geçerek zaten olması durumunda zaman kazanabiliriz . zaten mevcut olması durumunda " yalnızca için zaman alır .x∈STxO(lognT)
Kavşak testi
İki kümenin ve kesişip kesişmediğini hızlı bir şekilde değerlendirmek için her kümenin dizini tam olarak korunur . Kümesi için , sadece set için endeksini kontrol ederek , biz zaman içinde belirleyebilir sadece olsun veya olmasın kesişen , ama biz de tüm set içeren bir ikili ağaç alabilirsiniz .SjSkSjSkO(logs)SjSkSj∩Sk
Eleman Kaldırma
Bir kümesinden öğesini silmek için , onu yalnızca kendisi için arama ağacından değil , dizinindeki kümeleri için kavşaklarının her birinden . Bu zaman , burada.xTTSj∩TSjO(slognT)nT=|T|
Silme Ayarla
Kayıt defteri arama yükü nedeniyle, çok sayıda kümeniz varsa, artık gerekli olmadığında kümelerin silinmesi istenebilir. Tüm kayıt geçerek, biz silebilir diğer tüm setleri dizinden süresi içinde temsil eden arama ağacı silme maliyeti hakim, diğer kümenin her biri için , nerede.SSjO(snT)Sj∩TSjnT=|T|
Uyarılar
Yalnızca sabit sayıda küme uygulamayı bekliyorsanız, yukarıdaki çalışma süreleri şuna indirilir:
başlatma:O(1)
öğe ekleme:O(logn)
kavşak testi (ve kavşağın geri alınması):O(1)
öğe kaldırma:O(lognT)
silme işlemini ayarla:O(nS)
burada , kayıt defterindeki en büyük kümenin veüzerinde çalıştığınız takımı için.nnT=|T|T
Eğer olmasını bekliyorsanız nerede setleri, sizin evren sen bu işlemler alt doğrusal zamanda işletmek istiyorsanız, farklı bir veri yapısını gerekebilir. Ancak, kesişimini asla test etmeyeceğinizi bildiğiniz kümelerin çiftleri varsa, kümeler için dizinin boyutunu küçültebilirsiniz (kesişimini test edeceğiniz kümeleri dahil etmeyerek) veya birden fazla kayıt defteri ( kesişimini test edebileceğiniz her set koleksiyonu için bir tane). Aslında, bir kayıt defteri yalnızca her bir grup çiftinin dizinde birbirlerinin kaydını tutmasını sağlamak için merkezi kontrol istiyorsanız yararlıdır: bazı durumlarda, bir kümenin başlangıcında , sadece reklam kaydetmek için pratik olabilir hocO(|V|)VSher yeni set , ile kesişimini ilgilendiğiniz diğer kümelerinin indekslerine girer .TS