Dlaczego w .NET nie ma klasy Tree <T>?

87

Biblioteka klas bazowych w .NET ma doskonałe struktury danych dla kolekcji (lista, kolejka, stos, słownik), ale, co dziwne, nie zawiera żadnych struktur danych dla drzew binarnych. Jest to bardzo przydatna struktura dla niektórych algorytmów, na przykład wykorzystujących różne ścieżki przejścia. Szukam poprawnie napisanej, darmowej realizacji.

Czy jestem po prostu ślepy i nie znajduję go ... czy to jest zakopane gdzieś w BCL? Jeśli nie, czy ktoś może polecić darmową lub otwartą bibliotekę C # / .NET dla drzew binarnych? Najlepiej taki, który wykorzystuje leki generyczne.

EDYCJA: Aby wyjaśnić, czego szukam. Nie interesują mnie uporządkowane zbiory słowników, które wewnętrznie używają drzewa. Właściwie interesuje mnie drzewo binarne - takie, które ujawnia swoją strukturę, dzięki czemu można robić takie rzeczy, jak wyodrębnianie poddrzew lub przeprowadzanie przemierzania węzłów po naprawie. W idealnym przypadku taka klasa mogłaby zostać rozszerzona, aby zapewnić zachowanie wyspecjalizowanych drzew (np. Red / Black, AVL, Balanced, itp.).

L Bushkin
źródło
Zgoda. Czasami mam potrzebę znalezienia (w czasie O (Log N)) dwóch węzłów, które wiązały wartość (gdy wartość nie została znaleziona w kolekcji). Na przykład kolekcja (drzewo) zawiera 13 i 17 (między innymi), a ja szukam największego mniej niż i najmniej większego niż 16. Drzewo mogłoby to zrobić, ale Słowniki, posortowane listy i tablice skrótów przyjmują O (N) .
Les

Odpowiedzi:

31

Masz rację, w BCL nie ma nic. Podejrzewam, że dzieje się tak dlatego, że wybór, czy użyć drzewa, jest zwykle szczegółem implementacji, a poza tym jest niekonwencjonalnym sposobem dostępu do danych. Oznacza to, że nie mówisz „binarnego wyszukiwania elementu nr 37”; zamiast tego mówisz „zdobądź element # 37”.

Ale czy spojrzałeś na C5 ? Jest to bardzo przydatne i ma kilka implementacji drzew ( 1 , 2 , 3 ).

John Feminella
źródło
3
C5 obsługuje drzewa Red Black, a nie B-Tree. Są to różnice, o których ludzie powinni wiedzieć. B-Tree jest bardziej optymalne dla drzewa opartego na dysku lub drzewa opartego na dużej pamięci. Więcej węzłów jest przechowywanych w tej samej lokalizacji, dzięki czemu uzyskujesz lepszą wydajność pamięci podręcznej procesora i szybszy jest odczyt i zapis na dysku.
AnthonyLambert
68

Możesz zdefiniować własne:

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

Lub bez klucza:

public class MyTree<V> : HashSet<MyTree<V>>
{
    public V Value { get; set; }
}
Jason
źródło
To jednak wymaga, abyś wiedział, z iloma poziomami drzewa będziesz obsługiwać w czasie kompilacji, czy się mylę?
Veverke
1
Nie, kompilator C # obsługuje tę składnię.
Jason
2
Uważaj, że elementy nie są uporządkowane w ten sposób
Sebastian
@Veverke Być może myślałeś o szablonach C ++. .NET typy generyczne to typy środowiska uruchomieniowego.
Tom Blodget,
Jestem ciekawy. Jak tego używasz? Praktycznie? Jakaś próbka?
Syaiful Nizam Yahya
39

Czego byś chciał od takiej realizacji?

Drzewo binarne? Czerwony czarny? Drzewo Radix? B-drzewo? R-drzewo? R * -drzewo?

Drzewo jest bardziej wzorcem niż strukturą danych i jest zwykle używane tam, gdzie liczy się wydajność (więc szczegóły implementacji prawdopodobnie też mają znaczenie). Gdyby BCL zawierało jakąś klasę drzewa, i tak musiałbyś rzucić tylko własną

Alun Harford
źródło
1
Najlepsza odpowiedź na część pytania „dlaczego”.
Joel Coehoorn
A to tylko drzewa wyszukiwania. Są też drzewa ekspresji, warkocz decyzyjny, ...
Henk Holterman
Rzeczywiście, szczegóły implementacji mają znaczenie. W moim przypadku zamierzam zaimplementować algorytmy, które wykonałyby różne przejścia (infix, postfix) na zorganizowanym zestawie danych w ramach serii przekształceń. Struktura drzewa to najbardziej elegancki sposób rozwiązania mojego problemu.
LBushkin
11
W równoległym wszechświecie ktoś zadaje pytanie: „Dlaczego w .Net nie ma typów list?” I otrzymuje odpowiedź: „Czego byś chciał od takiej implementacji? Tablica? Połączona lista? Kolejka? A słownik?" Myślę, że to odpowiedź non sequitur.
rymdsmurf
12

SortedSet<T>jest implementowany jako binarne drzewo wyszukiwania ref . SortedDictionary<TKey, TValue>wewnętrznie korzysta z SortedSet<T>tego, więc jest również binarnym drzewem wyszukiwania ref .

Matt Brunell
źródło
5
Niestety są to po prostu implementacje uporządkowanych map i list. Żadne z nich nie jest pomocne przy ponownym użyciu jako drzewo binarne - te struktury drzewiaste są po prostu szczegółem implementacji kolekcji. Właściwie szukam klasy, która ujawnia strukturę drzewa.
LBushkin
9

Nie, Tree<T>w BCL nie ma żadnego typu „ -podobnego” (coś, co zawsze mnie również intrygowało), ale tutaj jest dobry artykuł , który przeprowadzi Cię przez proces implementacji własnego w C #.

Myślę, że można argumentować, że struktury danych oparte na drzewach są rzadziej używane w aplikacjach, do których zwykle używa się platformy .NET (aplikacje biznesowe, aplikacje do przenoszenia danych itp.). Mimo to zgadzam się z tobą, to dziwne, że BCL w ogóle nie ma implementacji.

Andrew Hare
źródło
-5

Istnieje TreeNode, którego możesz użyć. Nie jest on ogólny i ukryty w formularzach systemu Windows i używany z kontrolką treeview, ale można go również używać w innym miejscu.

Joel Coehoorn
źródło
Tak, ale ma tylko właściwość Tag o wartości System.Object ype. Brak ogólnego parametru <T>
Henk Holterman
3
Zawsze czuję się dziwnie, robiąc takie rzeczy. Jest to mniej widoczne w twoim konkretnym przykładzie, ale jeśli ludzie rutynowo zmieniają przeznaczenie klas z, powiedzmy, zależności, może to skutkować trudnymi do wyjaśnienia zależnościami i może wpędzić cię w kłopoty, jeśli zmieniona klasa zmieni się w nieoczekiwany sposób wersje zależności.
Paul Morie
4
Jaka byłaby korzyść z jej używania? Węzeł drzewa zwykle nie ma żadnej odpowiedniej funkcjonalności. Po prostu zawiera odniesienia do dzieci i ewentualnie rodzica. Nie ma powodu, aby nadużywać do tego klasy System.Windows.Forms! Po prostu napisz to sam - za minutę lub mniej.
user492238