2009-06-02 10 views
72

La libreria di classi base in .NET ha alcune eccellenti strutture dati per le raccolte (Elenco, Coda, Catasta, Dizionario), ma stranamente non contiene alcuna struttura di dati per alberi binari. Questa è una struttura terribilmente utile per determinati algoritmi, come quelli che traggono vantaggio da diversi percorsi trasversali. Sto cercando un'implementazione corretta, scritta e libera.Perché non esiste una classe di albero <T> in .NET?

Sono semplicemente cieco, e non trovandolo ... è sepolto da qualche parte nel BCL? In caso contrario, qualcuno può raccomandare una libreria C# /. NET libera o open-source per alberi binari? Preferibilmente uno che impiega generici.

MODIFICA: Per chiarire quello che sto cercando. Non sono interessato alle raccolte di dizionari ordinate che usano 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 traversal post-fix sui nodi. Idealmente, una tale classe potrebbe essere estesa per fornire i comportamenti di alberi specializzati (ad esempio Rosso/Nero, AVL, Bilanciato, ecc.).

+0

e su LinkedList ? –

+0

concordato. Occasionalmente ho la necessità di trovare (in tempo O (Log N)) i due nodi che hanno associato un valore (quando il valore non è stato trovato nella raccolta). Ad esempio la collezione (albero) contiene 13 e 17 (tra gli altri) e sto cercando il massimo minore e minore di 16. Un albero potrebbe farlo, ma Dizionari, liste ordinate e tabelle hash prendono O (N) . – Les

risposta

26

Hai ragione, non c'è nulla 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 "prendimi l'elemento # 37".

Ma hai dato un'occhiata a C5? È super pratico e ha diverse implementazioni di alberi (1, 2, 3).

+2

C5 supporta alberi Black Red e B-Tree. Sono differenze di cui le persone dovrebbero essere consapevoli. B-Tree è più ottimale per un albero basato su disco o una grande struttura basata sulla memoria. Più nodi vengono mantenuti nella stessa località in modo da ottenere prestazioni migliori della cache del processore e leggere più rapidamente su disco. – AnthonyLambert

8

No, non c'è alcun tipo "Tree<T> -like" nel BCL (qualcosa che mi ha sempre perplesso) ma here is a good article che vi guiderà attraverso l'implementazione del proprio in C#.

Immagino che si possa argomentare che le strutture di dati ad albero sono utilizzate meno comunemente nel tipo di applicazioni per le quali .NET viene solitamente utilizzato (app aziendali, applicazioni di spostamento dati, ecc.). Comunque, sono d'accordo con te, è strano che il BCL non abbia alcuna implementazione.

-5

C'è uno TreeNode che è possibile utilizzare. Non è generico e nascosto nei moduli di Windows e utilizzato con il controllo TreeView, ma è possibile utilizzarlo anche altrove.

+0

Sì, ma ha solo una proprietà Tag di System.Object ype. No Generico parametro –

+1

Mi sento sempre strano nel fare cose del genere. È meno visibile con il tuo esempio specifico, ma se le persone riutilizzano abitualmente le classi da, ad esempio, le dipendenze, ciò può portare a dipendenze difficili da spiegare e può metterti nei guai se la classe ri-proposta cambia in modo imprevisto attraverso versioni di dipendenza. –

+3

Quale sarebbe il profitto di usarlo? Di solito un nodo dell'albero non ha alcuna funzionalità rilevante in esso. Tiene solo i riferimenti ai bambini e alla fine un genitore. Nessun motivo per abusare di una classe System.Windows.Forms! Scrivilo tu stesso - in un minuto o meno. – user492238

12

SortedSet<T> è implementato come un albero binario di ricerca ref. SortedDictionary<TKey, TValue> utilizza internamente SortedSet<T> quindi è anch'esso un albero di ricerca binario ref.

+5

Purtroppo queste sono semplicemente implementazioni di mappe e liste ordinate. Né è utile per il riutilizzo come un albero binario - queste strutture ad albero sono semplicemente un dettaglio di implementazione della collezione. In realtà sto cercando una classe che esponga la struttura ad albero. – LBushkin

35

Cosa vorresti da una simile implementazione?

Albero binario? Rosso-nero? Albero Radix? B-tree? R-tree? R * -tree?

Un albero è più un modello che una struttura di dati e tendono ad essere utilizzati laddove le prestazioni sono importanti (quindi anche i dettagli di implementazione sono importanti). Se il BCL incluso una sorta di albero di una classe, dovreste solo rotolare il proprio comunque

+1

La migliore risposta per la parte "perché" della domanda. –

+0

E quelli sono solo gli alberi di ricerca. Ci sono anche alberi di espressione, alberi di decisione, ... –

+0

In effetti, i dettagli dell'implementazione sono importanti. Nel mio caso, sto cercando di implementare alcuni algoritmi che eseguono diversi attraversamenti (infisso, postfisso) 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

65

Si potrebbe definire il proprio:

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; } 
} 
+2

Huh. Intelligente. :) – JerKimball

+2

Sì, questo è intelligente. +1 –

+2

Semplice. Genio. –

Problemi correlati