Не с неизменяемых классов случае. Это циклическая зависимость: вам нужен родительский элемент для создания дочерних элементов, но вам также нужны дети для создания родителя. С другой стороны, большинству алгоритмов обхода дерева действительно не нужен родительский элемент, поскольку родительский элемент обычно находится в стеке или может быть где-то сохранен.
Да, мы, как правило, представляют их с одноплодной инстанции (object
) признака:
case object EmptyNode extends Tree
Есть много алгоритмов там, поиск в ширину и глубиной первого поиска являются наиболее распространенными , Это хорошее упражнение для их реализации. Но немного помощи со стороны Scala, мы обычно картина матча на left
и right
увидеть, что нам нужно делать дальше:
tree: Tree match {
case EmptyNode => // do nothing, return, etc.
case Node(left, value, right) =>
// Do inorder, preorder, postorder operation order
// You will also probably be processing left and right as well
}
Нет, ваше предположение верно, что использование неизменяемых классов регистра в дереве довольно сложно обновить, потому что, если вы обновляете листовой узел, вы должны воссоздать все выше него. Есть так называемые библиотеки Lenses и Lens, которые могут помочь вам в этом, хотя они могут быть немного более продвинутыми. Один популярный в Скале - Monocle.
Похоже, вы только начинаете с программированием или новой для Scala, поэтому я бы рекомендовал использовать var
-s вместо val
с:
case class Node(var left: Tree, var value: String, var right: Tree) extends Tree
Кроме того, если ваши черты уплотняются (sealed trait Tree
), тогда компилятор скажет вам, не обработал ли вы один из подтипов в совпадении с шаблоном.
EDIT:
На основе комментариев начать работать с этим:
sealed trait Tree
case class Node(var left: Tree, var value: String, var right: Tree, var parent: Tree) extends Tree
case object EmptyNode extends Tree
Да, по умолчанию, когда вы определили 'Node',' left', 'value',' right' определены как 'val'-s, что означает, что вы не можете их обновить. Если вы хотите изменить, тогда напишите 'var' перед ними, как я сделал в последней части моего ответа. После этого вы можете свободно обновлять атрибуты всякий раз. –
Да, хорошо выглядит и компилируется! Удачи! (Обновление: возможно, добавьте 'sealed' перед' trait Tree', поскольку я упомянул, что компилятор поможет и поймает ошибки для вас). –
Теперь, если я хотел добавить ребенка к тому, что у меня есть до сих пор, я делаю myTree.left = Node (что угодно)? – user4992519