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

时间:2015-06-11 01:16:44

标签: scala tree binary-tree

我正在尝试在Scala中创建一个非常简单的二叉树来进行数据存储和遍历。

现在我有:

trait Tree
case class Node(left: Tree, value: String, right: Tree) extends Tree

我的问题:

  1. 如何添加指向父级的指针?

  2. 我可以以任何方式左右指向null吗?或根节点的父指针?

  3. 我如何实际遍历树?

  4. 更新节点的值是否容易?

2 个答案:

答案 0 :(得分:2)

  1. 不使用不可变的案例类。它是循环依赖:您需要父级来创建子级,但您还需要子级来创建父级。另一方面,大多数树遍历算法并不真正需要父代,因为父代通常在堆栈中或者可以存储在某个地方。

  2. 是的,我们通常使用特征的单例实例(object)表示这些特征:

    case object EmptyNode extends Tree
    
  3. 有很多算法,广度优先搜索和深度优先搜索是最常见的。实施它们是一个很好的练习。但是对于Scala方面的一些帮助,我们通常会在leftright上进行模式匹配,以了解我们下一步需要做什么:

    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
    }
    
  4. 不,您的猜测是正确的,在树中使用不可变的案例类很难更新,因为如果更新叶节点,则必须重新创建它上面的所有内容。所谓的镜头和镜头库可以帮助你解决这个问题,尽管它们可能会更先进一些。 Scala中一个受欢迎的版本是Monocle

  5. 看起来你刚开始编程或者是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
    

答案 1 :(得分:0)

如果它对需要二叉树设施的程序员很有用,我写了一些可以继承和/或混合的Scala特性,以提供基本的红黑树功能,以及一些其他基于树的算法:

http://erikerlandson.github.io/blog/2015/09/26/a-library-of-binary-tree-algorithms-as-mixable-scala-traits/