scala二叉树,添加一个元素

时间:2014-11-27 08:33:17

标签: scala binary-tree covariance

我正在尝试更改二叉树中的结束节点。如何制作方法change_right_tree和change_left_tree?

编译器抱怨我正在重新分配给val。但是当我把东西改成var时,我会得到协变错误。

sealed abstract class Tree[+T] {
}
case object End extends Tree[Nothing] {
  override def toString = "."
}

case class Node[+T](var question: String,  left: Tree[T] = End, right: Tree[T] = End) extends Tree[T] {
  override def toString = "T(" + question.toString + " " + left.toString + " " + right.toString + ")"

  def set_question(str : String) = {question = str}

  def get_answer(answer : Boolean) = {
    if (answer){
      left
    }else {
      right
    }
  }
  // unclear on what I need to do to make this work
  def change_left_tree( new_tree : Tree[T]) = {this.left = new_tree}
  def change_right_tree( new_tree : Tree[T]) = {this.right = new_tree}
}

2 个答案:

答案 0 :(得分:1)

解决方案:如果您删除' +'从Node类声明中,您的代码将被编译。

说明:

当您使用协变类型[+ T]声明类时,您可以声明具有较窄类型的子类。因此,必须使用协变类型声明Tree类以允许声明case对象End。

但是当你希望它是可变的时,声明具有协变类型[+ T]的类Node是不正确的。为了理解它,最好想象一下编译器没有阻止你并允许你编译下面的代码(为了简单起见,我删除了其他方法):

case class Node[+T](var question: String, var left: Tree[T] = End, var right: Tree[T] = End)  extends Tree[T] {
    def change_left_tree( new_tree : Tree[T]) = {this.left = new_tree}
    def change_right_tree( new_tree : Tree[T]) = {this.right = new_tree}
}

现在您可以执行以下操作:

val stringNode:Node[String] = new Node("string node")
val intNode:Node[Int] = new Node("int node")
val anyNode:Node[Any] = stringNode
anyNode.change_left_tree(intNode)

现在Node [Int]是Node [String]的左侧节点。所以混合协方差和可变性会打破类型安全。

答案 1 :(得分:0)

  1. 在Node的定义中,左右属性已定义为End。
  2. 在change_left_tree和change_right_tree方法中,您需要修改左右值,而不是返回新树。
  3. def change_left_tree( new_tree : Tree[T]): Tree = {
      new Tree (this.question, new_tree, this.right)
    
         

    }