.NET'te neden Tree <T> sınıfı yok?


89

.NET'teki temel sınıf kitaplığı, koleksiyonlar için bazı mükemmel veri yapılarına sahiptir (Liste, Sıra, Yığın, Sözlük), ancak garip bir şekilde ikili ağaçlar için herhangi bir veri yapısı içermemesi yeterlidir. Bu, farklı geçiş yollarından yararlananlar gibi belirli algoritmalar için son derece kullanışlı bir yapıdır. Doğru yazılmış, ücretsiz bir uygulama arıyorum.

Ben sadece kör müyüm ve onu bulamıyorum ... BCL'de bir yere mi gömülü? Değilse, ikili ağaçlar için ücretsiz veya açık kaynaklı bir C # /. NET kitaplığı önerilebilir mi? Tercihen jenerik kullanan biri.

DÜZENLEME: Ne aradığımı açıklığa kavuşturmak için. Dahili olarak ağaç kullanan sıralı sözlük koleksiyonlarıyla ilgilenmiyorum. Aslında bir ikili ağaçla ilgileniyorum - yapısını ortaya çıkaran bir ağaç, böylece alt ağaçların çıkarılması veya düğümler üzerinde düzeltme sonrası geçişi gerçekleştirme gibi şeyler yapabilirsiniz. İdeal olarak, böyle bir sınıf, özelleşmiş ağaçların davranışlarını sağlamak için genişletilebilir (örn. Kırmızı / Siyah, AVL, Dengeli, vb.).


Kabul. Bazen bir değeri bağlayan iki düğümü (değer koleksiyonda bulunmadığında) bulmaya ihtiyacım olur (O (Log N) zamanında). Örneğin koleksiyon (ağaç) 13 ve 17 (diğerlerinin yanı sıra) içeriyor ve ben 16'dan küçük ve en az 16'dan büyük olanı arıyorum. Bir ağaç bunu yapabilir, ancak Sözlükler, sıralı listeler ve karma tablolar O (N) alır .
Les

Yanıtlar:


31

Haklısın, BCL'de hiçbir şey yok. Bunun nedeni, bir ağacın kullanılıp kullanılmayacağına ilişkin seçimin tipik olarak bir uygulama ayrıntısı olması ve bunun dışında verilere erişmek için alışılmadık bir yol olmasından kaynaklanıyor. Yani, "37 numaralı eleman için ikili arama" demezsiniz; bunun yerine "bana 37 numaralı öğeyi getir" diyorsun.

Ama C5'e bir göz attın mı? Çok kullanışlıdır ve birkaç ağaç uygulamasına sahiptir ( 1 , 2 , 3 ).


3
C5, B-Ağacı'nı değil Kırmızı Siyah ağaçları destekler. İnsanların farkında olması gereken farklılıklardır. B-Tree, disk tabanlı bir ağaç veya büyük bellek tabanlı ağaç için daha uygundur. Aynı yerde daha fazla düğüm tutulur, böylece daha iyi işlemci önbellek performansı elde edersiniz ve diske yazmak daha hızlı okunur.
AnthonyLambert

69

Kendiniz tanımlayabilirsiniz:

public class MyTree<K, V> : Dictionary<K, MyTree<K, V>>
{
    public V Value { get; set; }
}

Veya anahtarsız:

public class MyTree<V> : HashSet<MyTree<V>>
{
    public V Value { get; set; }
}

Ancak bu, derleme sırasında kaç ağaç düzeyini kullanacağınızı bilmenizi gerektirir, yanılıyor muyum?
Veverke

1
Hayır, C # derleyicisi bu sözdizimini destekler.
Jason

3
Unsurların bu şekilde sıralanmamasına dikkat edin
Sebastian

@Veverke Belki de C ++ şablonlarını düşünüyordunuz. .NET jenerikleri çalışma zamanı türleridir.
Tom Blodget

Merak ediyorum. Bunu nasıl kullanıyorsun Pratikte? Herhangi bir örnek?
Syaiful Nizam Yahya

39

Böyle bir uygulamadan ne isterdiniz?

İkili ağaç? Kırmızı siyah? Radix ağacı mı? B-ağacı mı? R-ağacı mı? R * -ağaç?

Bir ağaç, bir veri yapısından çok bir kalıptır ve performansın önemli olduğu yerlerde kullanılma eğilimindedir (bu nedenle uygulama ayrıntıları da muhtemelen önemlidir). BCL bir tür ağaç sınıfı içeriyorsa, yine de yalnızca kendi sınıfınızı atmanız gerekir.


1
Sorunun "neden" kısmı için en iyi cevap.
Joel Coehoorn

Ve bunlar sadece arama ağaçları. Bir de ifade ağaçları, karar ağaçları, ...
Henk Holterman

Gerçekten de uygulama detayları önemlidir. Benim durumumda, bir dizi dönüşümün parçası olarak organize bir veri kümesi üzerinde farklı geçişler (infix, postfix) gerçekleştirecek bazı algoritmalar uygulamaya çalışıyorum. Bir ağaç yapısı problemimi çözmenin en zarif yoludur.
LBushkin

12
Paralel bir evrende birisi şu soruyu soruyor: "Neden .Net'te liste türü yok?" Ve yanıtı alıyor: "Böyle bir uygulamadan ne istiyorsunuz? Bir dizi mi? Bağlantılı bir liste mi? Bir kuyruk mu? sözlük?" Bunun ardışık olmayan bir cevap olduğunu düşünüyorum.
rymdsmurf


12

SortedSet<T>bir ikili arama ağacı ref olarak uygulanır . SortedDictionary<TKey, TValue>dahili olarak yararlanır, SortedSet<T>bu yüzden de bir ikili arama ağacı ref .


5
Ne yazık ki bunlar sıralı haritaların ve listelerin basit uygulamalarıdır. İkili ağaç olarak yeniden kullanım için de yararlı değildir - bu ağaç yapıları, koleksiyonun yalnızca bir uygulama ayrıntısıdır. Aslında ağaç yapısını ortaya çıkaran bir sınıf arıyorum.
LBushkin

9

Hayır, Tree<T>BCL'de " benzeri" bir tür yok (beni her zaman şaşırtmış bir şey) ama burada C # 'da kendi yazınızı uygulamanız için size yol gösterecek iyi bir makale var.

Sanırım ağaç tabanlı veri yapılarının .NET'in genellikle kullanıldığı uygulamalarda (iş uygulamaları, veri taşıma uygulamaları, vb.) Daha az yaygın olarak kullanıldığını iddia edebilirsiniz. Yine de size katılıyorum, BCL'nin hiç uygulanmaması garip.



-5

Kullanabileceğiniz bir TreeNode var. Genel değildir ve pencere formlarında gizlenmez ve ağaç görünümü denetimiyle birlikte kullanılır, ancak başka yerlerde de kullanabilirsiniz.


Evet, ama sadece System.Object ype'nin Tag özelliğine sahip. Genel <T> parametresi yok
Henk Holterman

3
Böyle şeyler yaptığım için kendimi hep tuhaf hissediyorum. Özel örneğinizle daha az görünür, ancak insanlar rutin olarak sınıfları örneğin bağımlılıklardan yeniden kullanırsa, bu açıklanması zor bağımlılıklara neden olabilir ve yeniden amaçlanan sınıf beklenmedik bir şekilde değişirse başınızı belaya sokabilir. bağımlılık sürümleri.
Paul Morie

4
Kullanmanın karı ne olur? Bir ağaç düğümünde genellikle herhangi bir ilgili işlev bulunmaz. Sadece çocuklara ve nihayetinde bir ebeveyne göndermeler içerir. Bunun için System.Windows.Forms sınıfını kötüye kullanmak için bir neden yok! Sadece kendiniz yazın - bir dakika veya daha kısa sürede.
user492238
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.