Я думаю, что есть несколько причин, почему нет деревьев STL. В первую очередь, деревья - это форма рекурсивной структуры данных, которая, подобно контейнеру (список, вектор, набор), имеет очень отличную тонкую структуру, что затрудняет правильный выбор. Их также очень легко построить в базовой форме с использованием STL.
Конечное корневое дерево может рассматриваться как контейнер, который имеет значение или полезную нагрузку, скажем, экземпляр класса A и, возможно, пустую коллекцию корневых (под) деревьев; деревья с пустой коллекцией поддеревьев считаются листьями.
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
{};
Нужно немного подумать о дизайне итератора и т. Д. И о том, какие операции с продуктом и сопутствующим продуктом можно определять и быть эффективными между деревьями - и исходный STL должен быть хорошо написан - так, чтобы пустой контейнер набора, вектора или списка был действительно пустой из любой полезной нагрузки в случае по умолчанию.
Деревья играют существенную роль во многих математических структурах (см. Классические статьи Бучера, Гроссмана и Ларсена; также работы Конна и Кримера для примеров их объединения и того, как они используются для перечисления). Неправильно думать, что их роль заключается просто в облегчении некоторых других операций. Скорее они облегчают эти задачи из-за их фундаментальной роли как структуры данных.
Тем не менее, в дополнение к деревьям есть также «деревья»; деревья, прежде всего, обладают тем свойством, что при удалении корня вы удаляете все.
Рассмотрим итераторы на дереве, возможно, они будут реализованы как простой стек итераторов для узла и его родителя ... вплоть до корня.
template<class TREE>
struct node_iterator : std::stack<TREE::iterator>{
operator*() {return *back();}
...};
Тем не менее, вы можете иметь столько, сколько хотите; вместе они образуют «дерево», но там, где все стрелки текут в направлении к корню, это совместное дерево может быть перебрано с помощью итераторов к тривиальным итераторам и корню; однако он не может перемещаться по или вниз (другие итераторы ему неизвестны), и ансамбль итераторов не может быть удален, кроме как путем отслеживания всех экземпляров.
Деревья невероятно полезны, у них много структуры, поэтому очень сложно получить окончательно правильный подход. На мой взгляд, именно поэтому они не реализованы в STL. Более того, в прошлом я видел, как люди становятся религиозными и находят идею типа контейнера, содержащего экземпляры своего собственного типа, сложной - но им приходится с этим сталкиваться - это то, что представляет собой тип дерева - это узел, содержащий возможно пустая коллекция (меньших) деревьев. Текущий язык разрешает это без проблем, предоставляя конструктор по умолчанию для container<B>
не выделяет место в куче (или где-либо еще) для и B
т. Д.
Я, например, был бы рад, если бы это в хорошей форме нашло свое отражение в стандарте.