Estaba buscando una estructura de datos de árbol o gráfico en C #, pero supongo que no se proporciona ninguno. Un extenso examen de las estructuras de datos con C # 2.0 explica un poco sobre por qué. ¿Existe una biblioteca conveniente que se usa comúnmente para proporcionar esta funcionalidad? Quizás a través de un patrón de estrategia para resolver los problemas presentados en el artículo.
Me siento un poco tonto implementando mi propio árbol, tal como lo haría con mi propia ArrayList.
Solo quiero un árbol genérico que pueda estar desequilibrado. Piensa en un árbol de directorios. C5 parece ingenioso, pero sus estructuras de árbol parecen implementarse como árboles equilibrados rojo-negros más adecuados para la búsqueda que para representar una jerarquía de nodos.
fuente
Respuestas:
Mi mejor consejo sería que no exista una estructura de datos de árbol estándar porque hay tantas maneras de implementarla que sería imposible cubrir todas las bases con una sola solución. Cuanto más específica sea una solución, es menos probable que sea aplicable a cualquier problema dado. Incluso me molesta con LinkedList, ¿qué pasa si quiero una lista circular vinculada?
La estructura básica que necesitará implementar será una colección de nodos, y aquí hay algunas opciones para comenzar. Supongamos que la clase Node es la clase base de toda la solución.
Si solo necesita navegar por el árbol, una clase Node necesita una Lista de hijos.
Si necesita navegar por el árbol, la clase Node necesita un enlace a su nodo padre.
Cree un método AddChild que se ocupe de todos los detalles de estos dos puntos y de cualquier otra lógica de negocios que deba implementarse (límites secundarios, clasificación de los elementos secundarios, etc.)
fuente
Implementación recursiva simple ... <40 líneas de código ... Solo necesita mantener una referencia a la raíz del árbol fuera de la clase, o envolverla en otra clase, ¿tal vez cambiar el nombre a TreeNode?
fuente
Action<T>
delegado:public void traverse(NTree<T> node, Action<T> visitor)
. Acción <> 's firma es:void Action<T>( T obj )
. También hay versiones de 0 a 4 parámetros diferentes. También hay un delegado análogo para funciones llamadoFunc<>
.--i == 0
funcionará solo en un solo caso? Es esto cierto. Esto me hizo confundirAquí está el mío, que es muy similar al de Aaron Gage , un poco más convencional, en mi opinión. Para mis propósitos, no me he encontrado con ningún problema de rendimiento con
List<T>
. Sería bastante fácil cambiar a LinkedList si fuera necesario.fuente
public TreeNode<T> InsertChild(TreeNode<T> parent, T value) { var node = new TreeNode<T>(value) { Parent = parent }; parent._children.Add(node); return node; }
var five = myTree.AddChild(5); myTree.InsertChild(five, 55);
Otra estructura de árbol más:
Uso de la muestra:
BONIFICACIÓN
Ver árbol de pleno derecho con:
https://github.com/gt4dev/yet-another-tree-structure
fuente
node
viene ¿Significa que tengo que iterar sobre el árbol para usar el código de búsqueda?IEnumerable<>
miembros, por lo que no se compila.La generalmente excelente Biblioteca de colecciones genéricas C5 tiene varias estructuras de datos diferentes basadas en árboles, incluidos conjuntos, bolsas y diccionarios. El código fuente está disponible si desea estudiar los detalles de su implementación. (He usado colecciones C5 en código de producción con buenos resultados, aunque no he usado ninguna de las estructuras de árbol específicamente).
fuente
Ver http://quickgraph.codeplex.com/
QuickGraph proporciona estructuras de datos y algoritmos de gráficos genéricos dirigidos / no dirigidos para .Net 2.0 y versiones posteriores. QuickGraph viene con algoritmos tales como búsqueda de profundidad, búsqueda de respiración, búsqueda A *, ruta más corta, ruta k-más corta, flujo máximo, árbol de expansión mínimo, antepasados menos comunes, etc. QuickGraph admite MSAGL, GLEE y Graphviz para renderizar los gráficos, la serialización a GraphML, etc.
fuente
Si desea escribir el suyo, puede comenzar con este documento de seis partes que detalla el uso efectivo de las estructuras de datos de C # 2.0 y cómo analizar su implementación de estructuras de datos en C #. Cada artículo tiene ejemplos y un instalador con ejemplos que puede seguir.
"Un extenso examen de las estructuras de datos utilizando C # 2.0" por Scott Mitchell
fuente
Tengo una pequeña extensión a las soluciones.
Usando una declaración genérica recursiva y una subclase derivada, puede concentrarse mejor en su objetivo real.
Tenga en cuenta que es diferente de una implementación no genérica, no necesita emitir 'nodo' en 'NodeWorker'.
Aquí está mi ejemplo:
fuente
Aquí está el mío:
Salida:
fuente
Prueba esta simple muestra.
fuente
Creo una clase Node que podría ser útil para otras personas. La clase tiene propiedades como:
También existe la posibilidad de convertir una lista plana de elementos con un Id y un ParentId en un árbol. Los nodos tienen una referencia tanto a los hijos como a los padres, por lo que los nodos iterativos son bastante rápidos.
fuente
Como no se menciona, me gustaría llamar la atención sobre la base de código .net ahora lanzada: específicamente el código para un
SortedSet
que implementa un Árbol Rojo-Negro:https://github.com/Microsoft/referencesource/blob/master/System/compmod/system/collections/generic/sortedset.cs
Sin embargo, esta es una estructura de árbol equilibrada. Entonces, mi respuesta es más una referencia a lo que creo que es la única estructura de árbol nativa en la biblioteca principal de .net.
fuente
He completado el código que @Berezh ha compartido.
fuente
Aquí hay un árbol
Incluso puedes usar inicializadores:
fuente
La mayoría de los árboles están formados por los datos que está procesando.
Otro ejemplo es un árbol de análisis en un compilador ...
Lo que muestran estos dos ejemplos es que el concepto de árbol es parte del dominio de los datos y el uso de un árbol de propósito general separado al menos duplica el número de objetos que se crean y hace que la API sea más difícil de programar nuevamente.
Lo que queremos es una forma de reutilizar las operaciones de árbol estándar, sin tener que volver a implementarlas para todos los árboles, al mismo tiempo, sin tener que usar una clase de árbol estándar. Boost ha intentado resolver este tipo de problema para C ++, pero aún no he visto ningún efecto para .NET adaptarse.
fuente
He agregado una solución completa y un ejemplo usando la clase NTree anterior, también agregué el método "AddChild" ...
utilizando
fuente
Aquí está mi implementación de BST
fuente
Si va a mostrar este árbol en la GUI, puede usar TreeView y TreeNode . (Supongo que técnicamente puede crear un TreeNode sin ponerlo en una GUI, pero tiene más sobrecarga que una simple implementación de TreeNode propia).
fuente
En caso de que necesite una implementación de estructura de datos de árbol enraizada que use menos memoria, puede escribir su clase de nodo de la siguiente manera (implementación de C ++):
fuente