Ayrı zincirleme için ikili arama ağaçlarını kullanarak bir karma tablosunu hızlandırmak mümkün müdür?


11

Ayrı zincirleme işleminde arama karmaşıklığını O (n) (bağlantılı listeyi kullanarak) O (log n) (BST kullanarak) azaltmak için ikili arama ağaçları kullanarak bir karma tablo uygulamak istiyorum. Bu yapılabilir ve eğer evet ise nasıl? Çözümün adım adım, mantığın uygulanması olup olmadığını anlamak daha kolay olurdu.

Hashtable'da (ayrı zincirleme kullanarak inşa) Arama süresini azaltmak istiyorum, ancak aynı zamanda ekleme süresinin artmasını istemiyorum. Projem için, çarpmaları azaltmak için karma işlevini değiştiremiyorum. Ancak ölçeklenebilirlik nedeniyle çarpışma oluyor. Bir şekilde bir iş bulmaya çalışıyorum, böylece bir şekilde en iyi erişim ile çalışabilir ve bir çarpışma durumunda zaman ekleyebilirim ... yani tüm algoritmayı yeniden yapılandırmaktan ziyade bir şeyin mevcut durumunu yönetmek için. Eğer dışarı çıkmazsa, yeniden yapılandırılması gerekecektir. Yani herhangi bir fikir?


4
Karma tablolar ve İkili Arama Ağaçları farklı kaplardır. Yani önerdiğiniz şeyi yapamazsınız (ya da terminolojik bir hata yapıyorsunuz).
Basile Starynkevitch

Bir ağaçtaki her düğüme bir karma / değer çifti koyabilirsiniz ... ama bu kötü bir karma tablo veya kötü bir ikili ağaç olurdu. Bunu neden yapmak istediğinize ve sonuçların neler yapabilmesini istediğinize dair bir açıklama yapmadan, bunun gerçekten cevap verilebileceğinden emin değilim.
Ixrec

1
@AK_: Evet, dediğin gibi bir şey. ikili arama ağacı kullanarak çarpışmalar işlemek istiyorum. daha net hale getirmek için sorumu biraz düzelttim.
Aviral

1
O zaman her kesici uç için O (n log n) cezası ile birlikte gelir . Genel olarak, çok fazla dolmaya başlayan bir karma tablonuz varsa (ve tolere edebileceğinizden daha uzun zincirleriniz varsa), karma değerini yeniden oluşturursunuz. Düzenli olarak 3 veya 4'ten daha uzun zincirlerle karşılaşırsanız, bir şeyler yanlıştır.

3
Çarpışma azaltma, açık adresleme ve tablonun dinamik yeniden boyutlandırılması için karma tabloda çok sayıda varyasyon vardır . Hangisi gereksinimlerinize uyuyor, incelemeniz gereken bir şey. Mevcut yaklaşımınız diğer yapılarla ayrı zincirleme

Yanıtlar:


11

Kısıtlamalarınız göz önüne alındığında, istediğiniz şey mümkündür.

analiz

Karma tablonun gücü, hızlı arama ve ekleme hızıdır. Bu hızı elde etmek için, tablodaki herhangi bir düzen benzemesinden vazgeçmek gerekir: yani girişlerin hepsi karışıktır. Listenin tablo girişi olarak kullanılması kabul edilebilir, çünkü çaprazlama O (n) iken, karma tablonun yeterince büyük olduğu ve tabloda depolanan nesnelerin kaliteli bir karma algoritması kullanılarak karma yapıldığı varsayıldığında listelerin kısa olma eğilimindedir.

İkili bir arama ağacının (BST) hızlı eklenmesi ve O (log 2 n) araması vardır . Ayrıca depoladığı öğelere bir kısıtlama getirir: öğeleri sipariş etmenin bir yolu olmalıdır. Ağaçta depolanan iki A ve B elemanı göz önüne alındığında , A'nın B'den önce gelip gelmediğini veya eşdeğer bir sıraya sahip olup olmadıklarını belirlemek mümkün olmalıdır .

Karma tablo böyle bir kısıtlama getirmez: karma tablodaki öğelerin iki özelliği olmalıdır. İlk olarak, eşdeğer olup olmadıklarını belirlemenin bir yolu olmalıdır; ikinci olarak, deterministik bir karma kodu hesaplamanın bir yolu olmalıdır. Sipariş bir gereklilik değildir.

Karma tablo öğelerinizin bir sırası varsa, aynı karma koduna (çarpışmalara) sahip nesneleri tutmak için bir BST'yi karma tablo girişi olarak kullanabilirsiniz. Bununla birlikte, O (log 2 n) araması ve eklemesi olan bir BST nedeniyle , tüm yapı (karma tablo artı BST) için en kötü durum, bir listeyi tablo girişi olarak kullanmaktan teknik olarak daha iyi olduğu anlamına gelir. BST uygulamasına bağlı olarak, bir listeden daha fazla depolama alanı gerektirir, ancak büyük olasılıkla daha fazla değil.

Normalde bir BST'nin genel giderleri ve davranışının, karma tablo kovaları olarak gerçek dünyadaki durumlara hiçbir şey getirmediğini unutmayın , bu nedenle bir listenin teorik zayıf performansı kabul edilebilir. Başka bir deyişle, karma tablosu, her bir listeye (grup) daha az öğe yerleştirerek listenin zayıflığını telafi eder. Bununla birlikte : Sorun özellikle karma tablo ifade edemez boyut artış, ve çarpışmalar bir karma tabloda tipik olandan daha sıktır.

uygulama

Buraya kod koymayacağım çünkü dürüst olmak gerekirse gerçekten gerekli değil ve yine de bir dil vermediniz.

Yapacağım şey, dilinizin standart kitaplığının içerdiği standart karma tabloyu yeni bir sınıfa kopyalamak, daha sonra tablo kovası türünü listeden bir ağaca değiştirmek. Dile ve standart kütüphanesine bağlı olarak, bu çok önemsiz bir şey olabilir.

Normalde bu şekilde kopyala ve yapıştır kodlamasını savunmam. Ancak, savaşta test edilmiş bir veri yapısını çok hızlı bir şekilde almanın kolay bir yoludur .


Asimptotik terimlerle, çarpışma işlemesi için bir ikili ağaç kullanmak , karma tablonun zaten amortize edilmiş O (1) performansını elde etmek için olağan hileler yapmış olması şartıyla , bir karma tablonun beklenen performansını değiştirmez . İyi performans sağlamak için karma değeri yeniden boyutlandırmak, kova başına beklenen öğelerin (ikili ağaçların boyutu) da küçük olması gerektiği anlamına gelir, böylece her iki şekilde de aynı beklenen itfa edilmiş O (1) elde edersiniz. En kötü durum için bile - herhangi bir dengeleme kısıtlaması olmadan, ikili ağaç için en kötü durum performansı, yine de bağlantılı bir liste gibi davranmasıdır.
Steve314

@ Steve314 Sorunun çok fazla çarpışma olduğunu aklınızda bulundurun, bu yüzden bir kovadan normalde bir karma tablosundan daha fazla öğe içermesini bekler.

İyi bir nokta - örneğin, sınırsız verilere sahip sabit boyutlu bir karma tablo için, karma tablonun asimptotik performansı, çarpışma yönetiminin asimptotik performansı ile aynıdır - karma tablosu yalnızca sabit faktörleri değiştirir.
Steve314

@ Steve314 doğru, eğer esas olarak karma tablosu her bir gruptaki eleman sayısını etkili bir şekilde sınırlayamazsa, asimptotik performans her grupta kullanılan alt veri yapısına düşer. Bunu netleştirmek için cevabıma bir paragraf ekledim.

7

Bir karma tablosunda çarpışma işlemesi için bir ikili ağaç kullanmak sadece mümkün değildir - yapıldı.

Walter Bright en iyi D programlama dilinin mucidi olarak bilinir , ancak aynı zamanda DMDScript adı verilen bir ECMAScript varyantı yazdı . Geçmişte, DMDScript'in bir başlık iddiası (veya muhtemelen bir ata - DScript adını hatırlıyorum), hashtable'larının birçok benzer dilde daha iyi performans gösterme eğilimindeydi. İkili ağaçlar kullanarak sebep - çarpışma yönetimi.

Bunun nereden geldiğini tam olarak hatırlamıyorum, ancak kullanılan ağaçlar saf ikili ağaçlardı, kısmi denge şeması (AVL, kırmızı-siyah veya herhangi bir şey değil) vardı, bu da hashtable'ın aşırı dolduğunda yeniden boyutlandırıldığını varsayarak mantıklı olduğunu varsayıyor ve saçma sapmaların saçma sapan oranlarını alamazsınız, ikili ağaçlar her zaman küçük olmalıdır. Temel olarak, en kötü durum hala çarpışma yönetimi için bağlantılı bir liste kullanmakla aynıdır (bir düğüm yerine düğüm başına iki işaretçi fiyatını ödemeniz dışında), ancak ortalama durum her karma kova içinde arama miktarını azaltır.

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.