Creo que hay varias razones por las cuales no hay árboles STL. Principalmente, los árboles son una forma de estructura de datos recursiva que, como un contenedor (lista, vector, conjunto), tiene una estructura fina muy diferente que dificulta las elecciones correctas. También son muy fáciles de construir en forma básica utilizando el STL.
Un árbol enraizado finito puede considerarse como un contenedor que tiene un valor o carga útil, digamos una instancia de una clase A y, una colección posiblemente vacía de (sub) árboles enraizados; Los árboles con una colección vacía de árboles se consideran hojas.
template<class A>
struct unordered_tree : std::set<unordered_tree>, A
{};
template<class A>
struct b_tree : std::vector<b_tree>, A
{};
template<class A>
struct planar_tree : std::list<planar_tree>, A
{};
Uno tiene que pensar un poco sobre el diseño del iterador, etc., y qué operaciones de productos y coproductos permite definir y ser eficientes entre árboles, y el STL original debe estar bien escrito, para que el conjunto vacío, el vector o el contenedor de la lista sea realmente vacío de cualquier carga útil en el caso predeterminado.
Los árboles juegan un papel esencial en muchas estructuras matemáticas (véanse los documentos clásicos de Butcher, Grossman y Larsen; también los documentos de Connes y Kriemer para ver ejemplos de cómo se pueden unir y cómo se usan para enumerar). No es correcto pensar que su papel es simplemente facilitar ciertas otras operaciones. Más bien facilitan esas tareas debido a su papel fundamental como estructura de datos.
Sin embargo, además de los árboles también hay "co-árboles"; los árboles sobre todo tienen la propiedad de que si eliminas la raíz, eliminas todo.
Considere los iteradores en el árbol, probablemente se realizarían como una simple pila de iteradores, a un nodo y a su padre, ... hasta la raíz.
template<class TREE>
struct node_iterator : std::stack<TREE::iterator>{
operator*() {return *back();}
...};
Sin embargo, puedes tener tantos como quieras; colectivamente forman un "árbol" pero donde todas las flechas fluyen en la dirección hacia la raíz, este co-árbol puede iterarse a través de iteradores hacia el iterador trivial y la raíz; sin embargo, no se puede navegar a través o hacia abajo (no se conoce a los otros iteradores) ni se puede eliminar el conjunto de iteradores excepto si se realiza un seguimiento de todas las instancias.
Los árboles son increíblemente útiles, tienen mucha estructura, esto hace que sea un desafío serio obtener el enfoque definitivamente correcto. En mi opinión, es por eso que no se implementan en el STL. Además, en el pasado, he visto a personas volverse religiosas y encontrar desafiante la idea de un tipo de contenedor que contiene instancias de su propio tipo, pero tienen que enfrentarlo, eso es lo que representa un tipo de árbol: es un nodo que contiene un posiblemente colección vacía de árboles (más pequeños). El lenguaje actual lo permite sin problemas, ya que el constructor predeterminado container<B>
no asigna espacio en el montón (ni en ningún otro lugar) para un B
, etc.
Por mi parte, estaría satisfecho si esto, en buena forma, llegara a la norma.