在Scala中创建一个非常基本的二叉树

在Scala中创建一个非常基本的二叉树,scala,tree,binary-tree,Scala,Tree,Binary Tree,我试图在Scala中创建一个非常简单的二叉树,用于数据存储和遍历 现在我有: trait Tree case class Node(left: Tree, value: String, right: Tree) extends Tree 我的问题是: 如何还包括指向父级的指针 我可以以任何方式将左、右点设置为null吗?还是根节点的父指针 我怎样才能真正穿过这棵树呢 更新节点的值容易吗 不适用于不可变的case类。这是一个循环依赖关系:您需要父对象来创建子对象,但也需要子对象来创建父对象。另一

我试图在Scala中创建一个非常简单的二叉树,用于数据存储和遍历

现在我有:

trait Tree
case class Node(left: Tree, value: String, right: Tree) extends Tree
我的问题是:

  • 如何还包括指向父级的指针

  • 我可以以任何方式将左、右点设置为null吗?还是根节点的父指针

  • 我怎样才能真正穿过这棵树呢

  • 更新节点的值容易吗

  • 不适用于不可变的case类。这是一个循环依赖关系:您需要父对象来创建子对象,但也需要子对象来创建父对象。另一方面,大多数树遍历算法实际上并不需要父级,因为父级通常位于堆栈上,或者可以存储在某个地方

  • 是的,我们通常用一个trait的单例实例(
    object
    )来表示:

    case object EmptyNode extends Tree
    
  • 有很多算法,广度优先搜索和深度优先搜索是最常见的。这是一个很好的实践。但在Scala方面,我们通常会在
    左侧
    右侧
    进行模式匹配,以查看下一步需要做什么:

    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
    }
    
  • 不,您的猜测是正确的,在树中使用不可变的case类是很难更新的,因为如果您更新一个叶节点,那么您必须重新创建它上面的所有内容。有一些所谓的镜头和镜头库可以帮助你做到这一点,尽管它们可能更先进一些。Scala中一个流行的是


  • 似乎您刚刚开始编程或刚刚接触Scala,因此我建议使用
    var
    -s而不是
    val
    s:

    case class Node(var left: Tree, var value: String, var right: Tree) extends Tree
    
    此外,如果您的特征是密封的(
    sealed trait Tree
    ),那么编译器将告诉您是否在模式匹配中没有处理其中一个子类型

    编辑:

    根据评论,开始使用以下内容:

    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
    

    是,默认情况下,当您定义
    节点
    时,
    都定义为
    val
    -s,这意味着您无法更新它们。如果你想要可变的,那么在他们前面写
    var
    ,就像我在回答的最后一部分所做的那样。之后,您可以随时自由更新属性。是的,看起来不错,并且可以编译!祝你好运(更新:可能在
    特征树
    前面添加
    sealed
    ,正如我提到的,编译器将帮助您捕获bug)。现在,如果我想在我目前拥有的内容中添加一个子项,我是否执行myTree.left=节点(无论什么)?是的,但您应该可以自己尝试一下!:)我不会整晚都在这里检查你的密码:D