Penso che ci siano diverse ragioni per cui non ci sono alberi STL. Principalmente gli alberi sono una forma di struttura di dati ricorsiva che, come un contenitore (elenco, vettore, set), ha una struttura fine molto diversa che rende difficili le scelte corrette. Sono anche molto facili da costruire in forma base usando l'STL.
Un albero con radice finita può essere pensato come un contenitore che ha un valore o un payload, ad esempio un'istanza di una classe A e, eventualmente, una raccolta vuota di (radici) alberi con radici; gli alberi con raccolta di sottotitoli vuoti sono considerati foglie.
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
{};
Bisogna pensare un po 'al design dell'iteratore ecc. E quali operazioni di prodotto e coprodotto si consentono di definire ed essere efficienti tra gli alberi - e l'STL originale deve essere ben scritto - in modo che il contenitore vuoto di set, vettore o elenco sia veramente vuoto di qualsiasi payload nel caso predefinito.
Gli alberi svolgono un ruolo essenziale in molte strutture matematiche (vedere gli articoli classici di Butcher, Grossman e Larsen; anche gli articoli di Connes e Kriemer per esempi di essi possono essere uniti e come vengono utilizzati per elencare). Non è corretto pensare che il loro ruolo sia semplicemente quello di facilitare alcune altre operazioni. Piuttosto facilitano tali compiti a causa del loro ruolo fondamentale come struttura di dati.
Tuttavia, oltre agli alberi ci sono anche "co-alberi"; gli alberi hanno soprattutto la proprietà che se si elimina la radice si elimina tutto.
Considera gli iteratori sull'albero, probabilmente verrebbero realizzati come una semplice pila di iteratori, su un nodo e sul suo genitore, ... fino alla radice.
template<class TREE>
struct node_iterator : std::stack<TREE::iterator>{
operator*() {return *back();}
...};
Tuttavia, puoi averne quanti ne desideri; collettivamente formano un "albero" ma dove tutte le frecce scorrono nella direzione verso la radice, questo co-albero può essere ripetuto attraverso iteratori verso il banale iteratore e radice; tuttavia non può essere navigato attraverso o verso il basso (gli altri iteratori non gli sono noti) né è possibile eliminare l'insieme di iteratori se non tenendo traccia di tutte le istanze.
Gli alberi sono incredibilmente utili, hanno molta struttura, questo rende una sfida seria ottenere l'approccio definitivamente corretto. A mio avviso, questo è il motivo per cui non sono implementati nell'STL. Inoltre, in passato, ho visto persone diventare religiose e trovare stimolante l'idea di un tipo di contenitore contenente istanze del proprio tipo - ma devono affrontarlo - questo è ciò che rappresenta un tipo di albero - è un nodo che contiene un raccolta forse vuota di alberi (più piccoli). La lingua corrente lo consente senza difficoltà fornendo il costruttore predefinito per container<B>
non allocare spazio sull'heap (o in qualsiasi altro luogo) per un B
, ecc.
Per quanto mi riguarda sarei contento se questo, in una buona forma, trovasse la sua strada nello standard.