Set Kavşağı için Veri Yapısı?


21

Aşağıdaki işlemleri destekleyen bir küme (sonlu zemin kümesinin) koleksiyonunu tutan herhangi bir veri yapısı var mı? Herhangi bir alt doğrusal çalışma süresi takdir edilecektir?

  1. Boş bir kümeyi başlatın.
  2. Kümeye bir öğe ekleyin.
  3. İki set verildiğinde kesişip kesişmediklerini bildirin.

1
Bu çok genel bir sorudur, çünkü herhangi bir veri yapısı sonlu etki alanı ile bu işlemleri destekleyebilir. Biraz daha spesifik olabilir misiniz? Örneğin. İhtiyacınız ne karmaşıklığı, istekli vb küme işlemleri için feda edeceğim nelerdir
Bartosz Przybylski

Yanıtlar:


13

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 jS k S j S kSjSkSjSkSjSk

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)TSjTTSj=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 jxVTO(lognT)nT=|T|xS1,S2,

O(lognS1+lognS2+)O(slogn),
n=|V|SjsSjxSjxSjTSjBu 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)SjTxSjTS1,S2,O(slogs+slognT)SjVsnO(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 .xSTxO(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)SjSkSjSk

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.xTTSjTSjO(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)SjTSjnT=|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


6

Bunu en kötü girişler için bile doğrusal zamandan daha kısa sürede yapmanızı sağlayan veri yapıları vardır. Bkz. Http://research.microsoft.com/pubs/173795/vldb11intersection.pdf (ve buradaki belgeler referansları).

İki kümeniz S ve T'nin büyük bir kesişimine sahipse ve S için bir sözlüğünüz varsa, T öğelerini rastgele sırayla aramak size hızlı bir şekilde ortak bir öğe vermelidir. En zor durum, kavşak büyüklüğünün 0 veya 1 olmasıdır.


3

Genellikle seçtiğiniz programlama diliniz benzersiz unsurlara sahip bir veri yapısını destekler. Genel olarak üç popüler yaklaşım vardır: Ağaçlar, Hashes ve Bitmasks. Ağaç öğeleri karşılaştırılabilir, Hash öğeleri yıkanabilir olmalı ve Bitmask öğeleri tamsayılara dönüştürülmelidir.

Bir ağaç seti, O (log n) içine yerleştirmeyi ve En Kötü Durum O (n log n) içinde kavşak testini destekleyecektir.

Bir karma-set, 'h' değerinin karma algoritmasının çalışma süresi olduğu Amortize O (1 * sa) içine yerleştirmeyi ve En Kötü Durum O (n) 'de kesişim testini destekleyecektir.

Bitmask kümeleri genellikle ağaç ve karma kümeleri gibi kullanılmaz.


2
Bu iyi bir Stack Overflow cevabı olacaktır, ancak burada nasıl ve neden çalıştığı hakkında biraz ayrıntı istiyoruz .
Raphael

3

Durumunuz yanlış pozitif cevaplara izin veriyorsa, Bloom Filter'ı tek bir hash işleviyle kullanırdım.

Aşağıdaki gibi uygulayabilirsiniz:

Boş bir kümeyi başlat

  • = bit dizisi , n bit, 0 için ayarlanmıştır ( n olası elemanların sayısı göre seçilmelidir)Bnn

Kümeye bir öğe ekleyin.

  • B[hash(element)]=1

İki küme (B1, B2) verildiğinde kesişip kesişmediklerini bildirin.

  • A N D B 2 = 0 olup olmadığını kontrol edinB1 AND B2 = 0

karmaşa

  • Eğer çok büyük olmadığından, tüm operasyonlardır Ç ( 1 ) .nO(1)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.