Pourquoi n'y a-t-il pas de classe Tree <T> dans .NET?

87

La bibliothèque de classes de base dans .NET a d'excellentes structures de données pour les collections (liste, file d'attente, pile, dictionnaire), mais curieusement, elle ne contient aucune structure de données pour les arbres binaires. C'est une structure terriblement utile pour certains algorithmes, tels que ceux qui tirent parti de différents chemins de traversée. Je recherche une implémentation gratuite et correctement écrite.

Suis-je simplement aveugle et ne le trouve pas ... est-il enterré quelque part dans la BCL? Sinon, quelqu'un peut-il recommander une bibliothèque C # / .NET gratuite ou open-source pour les arbres binaires? De préférence, celui qui utilise des génériques.

EDIT: Pour clarifier ce que je recherche. Je ne suis pas intéressé par les collections de dictionnaires ordonnées qui utilisent en interne un arbre. Je suis en fait intéressé par un arbre binaire - un arbre qui expose sa structure afin que vous puissiez faire des choses comme extraire des sous-arbres ou effectuer une traversée post-correction sur les nœuds. Idéalement, une telle classe pourrait être étendue pour fournir les comportements d'arbres spécialisés (c'est-à-dire rouge / noir, AVL, équilibré, etc.).

LBushkin
la source
D'accord. J'ai parfois besoin de trouver (en temps O (Log N)) les deux nœuds qui ont lié une valeur (lorsque la valeur n'est pas trouvée dans la collection). Par exemple, la collection (arbre) contient 13 et 17 (entre autres) et je recherche le plus grand inférieur et le moins supérieur à 16. Un arbre pourrait le faire, mais les dictionnaires, les listes triées et les tables de hachage prennent O (N) .
Les

Réponses:

31

Vous avez raison, il n'y a rien dans la BCL. Je soupçonne que cela est dû au fait que le choix d'utiliser ou non un arbre est généralement un détail de mise en œuvre et est par ailleurs un moyen non conventionnel d'accéder aux données. C'est-à-dire que vous ne dites pas "élément de recherche binaire # 37"; au lieu de cela, vous dites "récupérez-moi l'élément n ° 37".

Mais avez-vous jeté un œil à C5 ? C'est très pratique et ils ont plusieurs implémentations d'arbre ( 1 , 2 , 3 ).

John Feminella
la source
3
C5 prend en charge les arbres Red Black et non B-Tree. Ce sont des différences dont les gens devraient être conscients. B-Tree est plus optimal pour une arborescence basée sur disque ou une arborescence basée sur une grande mémoire. Davantage de nœuds sont conservés dans la même localité, ce qui vous permet d'obtenir de meilleures performances du cache du processeur et une lecture plus rapide sur le disque.
AnthonyLambert
68

Vous pouvez définir le vôtre:

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

Ou sans clé:

public class MyTree<V> : HashSet<MyTree<V>>
{
    public V Value { get; set; }
}
Jason
la source
Cela nécessite cependant que vous sachiez combien de niveaux d'arbre vous allez gérer au moment de la compilation, est-ce que je me trompe?
Veverke
1
Non, le compilateur C # prend en charge cette syntaxe.
Jason
2
Méfiez-vous que les éléments ne sont pas classés de cette façon
Sebastian
@Veverke Vous pensiez peut-être aux modèles C ++. Les génériques .NET sont des types d'exécution.
Tom Blodget du
Je suis curieux. Comment l'utilisez-vous? Pratiquement? Un échantillon?
Syaiful Nizam Yahya
39

Que souhaiteriez-vous d'une telle implémentation?

Arbre binaire? Rouge noir? Arbre Radix? B-arbre? R-tree? R * -arbre?

Un arbre est plus un modèle qu'une structure de données, et ils ont tendance à être utilisés là où les performances sont importantes (donc les détails d'implémentation comptent probablement aussi). Si la BCL incluait une sorte de classe d'arbre, vous n'auriez de toute façon qu'à rouler la vôtre

Alun Harford
la source
1
Meilleure réponse pour la partie «pourquoi» de la question.
Joel Coehoorn le
Et ce ne sont que les arbres de recherche. Il y a aussi des arbres d'expression, des arbres de décision, ...
Henk Holterman
En effet, les détails de mise en œuvre sont importants. Dans mon cas, je cherche à implémenter des algorithmes qui effectueraient différentes traversées (infixe, suffixe) sur un ensemble organisé de données dans le cadre d'une série de transformations. Une structure arborescente est le moyen le plus élégant de résoudre mon problème.
LBushkin
11
Dans un univers parallèle, quelqu'un pose la question: "Pourquoi n'y a-t-il pas de types de liste dans .Net?", Et ils obtiennent la réponse: "Que voudriez-vous d'une telle implémentation? Un tableau? Une liste liée? Une file d'attente? dictionnaire?" Je pense que c'est une réponse non séquentielle.
rymdsmurf
12

SortedSet<T>est implémenté comme un arbre de recherche binaire réf . SortedDictionary<TKey, TValue>utilise en interne SortedSet<T>donc c'est aussi un arbre de recherche binaire réf .

Matt Brunell
la source
5
Malheureusement, ce ne sont que des implémentations de cartes et de listes ordonnées. Ni l'un ni l'autre n'est utile pour la réutilisation en tant qu'arbre binaire - ces structures arborescentes sont simplement un détail d'implémentation de la collection. Je recherche en fait une classe qui expose l'arborescence.
LBushkin
9

Non, il n'y a pas de type " Tree<T>-like" dans la BCL (quelque chose qui m'a toujours aussi perplexe) mais voici un bon article qui vous guidera dans l'implémentation du vôtre en C #.

Je suppose que vous pourriez faire valoir que les structures de données basées sur des arbres sont moins couramment utilisées dans le type d'applications pour lesquelles .NET est habituellement utilisé (applications d'entreprise, applications de transfert de données, etc.). Pourtant, je suis d'accord avec vous, il est étrange que la BCL n'ait aucune implémentation.

Andrew Hare
la source
-5

Il y a un TreeNode que vous pouvez utiliser. Ce n'est pas générique et caché dans les formulaires Windows et utilisé avec le contrôle treeview, mais vous pouvez également l'utiliser ailleurs.

Joël Coehoorn
la source
Ouais, mais il a juste une propriété Tag de System.Object ype. Pas de paramètre générique <T>
Henk Holterman
3
Je me sens toujours bizarre de faire des trucs comme ça. C'est moins visible avec votre exemple spécifique, mais si les gens réorganisent régulièrement des classes à partir, par exemple, de dépendances, cela peut entraîner des dépendances difficiles à expliquer et peut vous causer des ennuis si la classe redéfinie change de manière inattendue. versions de dépendance.
Paul Morie
4
Quel serait l'intérêt de l'utiliser? Un nœud d'arbre ne contient généralement aucune fonctionnalité pertinente. Il contient juste des références aux enfants et éventuellement à un parent. Aucune raison de mal utiliser une classe System.Windows.Forms pour cela! Écrivez-le vous-même - en une minute ou moins.
user492238