Perché non esiste una classe Tree <T> in .NET?


89

La libreria di classi di base in .NET ha alcune eccellenti strutture di dati per le raccolte (List, Queue, Stack, Dictionary), ma stranamente non contiene strutture di dati per alberi binari. Questa è una struttura estremamente utile per alcuni algoritmi, come quelli che sfruttano diversi percorsi di attraversamento. Sto cercando un'implementazione gratuita e scritta correttamente.

Sono semplicemente cieco e non lo trovo ... è sepolto da qualche parte nella BCL? In caso contrario, qualcuno può consigliare una libreria C # /. NET gratuita o open source per alberi binari? Preferibilmente uno che impiega generici.

EDIT: per chiarire cosa sto cercando. Non sono interessato alle raccolte di dizionari ordinate che utilizzano internamente un albero. In realtà sono interessato a un albero binario, uno che espone la sua struttura in modo che tu possa fare cose come estrarre sottostrutture o eseguire attraversamenti post-correzione sui nodi. Idealmente una tale classe potrebbe essere estesa per fornire i comportamenti di alberi specializzati (es. Rosso / Nero, AVL, Bilanciato, ecc.).


Concordato. Di tanto in tanto ho la necessità di trovare (nel tempo O (Log N)) i due nodi che delimitano un valore (quando il valore non si trova nella raccolta). Ad esempio, la raccolta (albero) contiene 13 e 17 (tra gli altri) e sto cercando il maggiore minore e minore maggiore di 16. Un albero potrebbe farlo, ma dizionari, elenchi ordinati e tabelle hash accettano O (N) .
Les

Risposte:


31

Hai ragione, non c'è niente nel BCL. Sospetto che ciò sia dovuto al fatto che la scelta di utilizzare un albero è in genere un dettaglio di implementazione ed è altrimenti un modo non convenzionale per accedere ai dati. Cioè, non dici "binary-search-for element # 37"; invece, dici "dammi l'elemento # 37".

Ma hai dato un'occhiata al C5 ? È super pratico e hanno diverse implementazioni ad albero ( 1 , 2 , 3 ).


3
C5 supporta alberi Red Black non B-Tree. Sono differenze di cui le persone dovrebbero essere consapevoli. B-Tree è più ottimale per un albero basato su disco o grande albero basato su memoria. Più nodi vengono mantenuti nella stessa località in modo da ottenere migliori prestazioni della cache del processore ed è più veloce leggere la scrittura su disco.
AnthonyLambert

69

Potresti definire il tuo:

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

O senza chiave:

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

Ciò tuttavia richiede che tu sappia quanti livelli di albero gestirai in fase di compilazione, sbaglio?
Veverke

1
No, il compilatore C # supporta questa sintassi.
Jason

3
Attenzione che gli elementi non sono ordinati in questo modo
Sebastian

@Veverke Forse stavi pensando ai modelli C ++. I generici .NET sono tipi di runtime.
Tom Blodget,

Sono curioso. Come lo usi? In pratica? Qualche campione?
Syaiful Nizam Yahya

40

Cosa vorresti da una simile implementazione?

Albero binario? Rosso nero? Albero della radice? B-albero? R-tree? R * -albero?

Un albero è più un pattern che una struttura dati e tendono ad essere usati dove le prestazioni contano (quindi probabilmente anche i dettagli di implementazione contano). Se il BCL includesse una sorta di classe ad albero, dovresti comunque lanciarne una tua


1
Migliore risposta per la parte "perché" della domanda.
Joel Coehoorn

E quelli sono solo gli alberi di ricerca. Ci sono anche alberi delle espressioni, alberi delle decisioni, ...
Henk Holterman,

In effetti, i dettagli di implementazione contano. Nel mio caso, sto cercando di implementare alcuni algoritmi che eseguano diversi attraversamenti (infisso, suffisso) su un insieme organizzato di dati come parte di una serie di trasformazioni. Una struttura ad albero è il modo più elegante per risolvere il mio problema.
LBushkin

12
In un universo parallelo qualcuno pone la domanda: "Perché non ci sono tipi di lista in .Net?", E ottiene la risposta: "Cosa vorresti da una simile implementazione? Un array? Una lista collegata? Una coda? A dizionario?" Penso che questa sia una risposta non sequitur.
rymdsmurf


12

SortedSet<T>è implementato come un albero di ricerca binario ref . SortedDictionary<TKey, TValue>fa uso internamente SortedSet<T>quindi è anche un albero di ricerca binario rif .


5
Purtroppo queste sono semplicemente implementazioni di mappe ed elenchi ordinati. Nessuno dei due è utile per il riutilizzo come albero binario: queste strutture ad albero sono semplicemente un dettaglio di implementazione della raccolta. In realtà sto cercando una classe che esponga la struttura ad albero.
LBushkin

9

No, non c'è alcun Tree<T>tipo " simile" nel BCL (qualcosa che mi ha sempre lasciato perplesso) ma ecco un buon articolo che ti guiderà attraverso l'implementazione del tuo in C #.

Immagino che potresti sostenere che le strutture di dati basate su albero sono meno comunemente utilizzate nel tipo di applicazioni per cui .NET viene solitamente utilizzato (app aziendali, app per lo spostamento di dati, ecc.). Tuttavia, sono d'accordo con te, è strano che BCL non abbia alcuna implementazione.



-5

C'è un TreeNode che puoi usare. Non è generico e nascosto nei moduli di Windows e utilizzato con il controllo treeview, ma puoi usarlo anche altrove.


Sì, ma ha solo una proprietà Tag di System.Object ype. Nessun parametro <T> generico
Henk Holterman

3
Mi sento sempre strano nel fare cose del genere. È meno visibile con il tuo esempio specifico, ma se le persone riutilizzano regolarmente le classi da, diciamo, dipendenze, ciò può comportare dipendenze difficili da spiegare e può metterti nei guai se la classe riproposta cambia in modo inaspettato versioni di dipendenza.
Paul Morie

4
Quale sarebbe il profitto nell'usarlo? Un nodo dell'albero di solito non ha alcuna funzionalità rilevante al suo interno. Contiene solo riferimenti a bambini e alla fine a un genitore. Non c'è motivo di abusare di una classe System.Windows.Forms per questo! Scrivilo tu stesso - in un minuto o meno.
user492238
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.