Когда вы говорите «построенный из листьев», я предполагаю, что вы включаете тот факт, что конструктор принимает детей, но никогда не берет родителя.
кажется, что, если вы построили дерево в другом направлении, вы бы ввести возможность циклов.
Нет, потому что тогда у вас будет противоположное ограничение: конструктор должен будет взять родителя, но никогда не будет дочерним. Поэтому вы никогда не сможете создать потомка, пока не будут созданы все его предки. Поэтому никакие циклы не возможны.
Обдумав это немного больше, это кажется, что создание из листьев может быть единственным способом создания непреложного дерева. Я прав?
Нет ... см. Мои комментарии к Брайану и ergosys.
Для многих приложений дерево, дочерние узлы которого указывают на родителей, не очень полезно. Я даю это. Если вам нужно пересечь дерево в порядке, определяемом его иерархией, дерево с восходящим указателем делает это трудным.
Однако для других приложений такое дерево является именно тем видом, который мы хотим. Например, у нас есть база данных статей. Каждая статья может иметь один или несколько переводов. В каждом переводе могут быть переводы. Мы создаем эту структуру данных как таблицу реляционных баз данных, где каждая запись имеет «внешний ключ» (указатель) для своего родителя. Ни одна из этих записей никогда не должна менять свой указатель на родителя. Когда добавляется новая статья или перевод, запись создается с указателем на соответствующий родительский элемент.
Общим примером является запрос таблицы переводов, поиск переводов для определенной статьи или переводы на определенном языке. Ах, вы говорите, таблица переводов - изменяемая структура данных.
Несомненно. Но он отделен от дерева. Мы используем (неизменяемое) дерево для записи иерархических отношений и изменяемой таблицы для итерации по элементам. В ситуации, отличной от базы данных, вы можете иметь хеш-таблицу, указывающую на узлы дерева. В любом случае, само дерево (т. Е. Узлы) никогда не будет изменено.
Here's another example of this data structure, включая способы доступа к узлам.
Моя точка зрения заключается в том, что ответ на вопрос ОП «да», я согласен с остальными вами, что предотвращение циклов делает исходит из неизменности в одиночку. В то время как вы можете построить дерево в другом направлении (сверху вниз), если вы это сделаете, и оно неизменное, оно все еще не может иметь циклов.
Когда вы говорите о мощных теоретических гарантий, как
еще одна приятная особенность неизменных структур данных является то, что невозможно случайно (или намеренно !) Создать дерево, которое содержит цикл [акцент в оригинале]
«такое дерево не очень полезно» бледнеет в сравнении - даже если это правда. Люди создают бесполезные структуры данных случайно, не говоря уже о создании якобы бесполезных намеренно. Предполагаемая бесполезность не защищает программу от ошибок циклов в ваших структурах данных. Теоретическая гарантия (если вы действительно соответствуете указанным критериям).
P.S. одна хорошая особенность деревьев, указывающих вверх, заключается в том, что вы можете гарантировать один аспект определения деревьев, что структуры дерева древовидных деревьев (например, Эрик Липперт) не делают: каждый узел имеет не более одного родителя. (См. David's comment и мой ответ.)
Поскольку структура данных неизменна, было бы невозможно, чтобы дерево было создано с другого направления, поэтому ваше предположение было равно утверждению Эрика? –
Да, это то, чего я не смог понять изначально. – Odrade
Почему все считают, что узел дерева должен хранить информацию о своих дочерних элементах, а не о его родительском? Есть ли определение в этом отношении где-то в статье? Мне кажется, что древовидная структура, в которой дочерние узлы указывают на родителя, является очень естественным и распространенным способом разработки вещей. Не то, чтобы что-то не так с указанием на своих детей, но это не единственный способ. – LarsH