二叉树折叠

时间:2016-09-27 06:35:29

标签: scala tree fold

我得到了以下二叉树的定义

abstract class Tree[+A]
case class Leaf[A](value: A) extends Tree[A]
case class Node[A](value: A, left: Tree[A], right: Tree[A]) extends Tree[A]

以及以下功能

def fold_tree[A,B](f1: A => B)(f2: (A, B, B) => B)(t: Tree[A]): B = t match {
    case Leaf(value) => f1(value)
    case Node(value, l, r) => f2(value, fold_tree(f1)(f2)(l), fold_tree(f1)(f2)(r)) //post order
  }

我被要求使用fold方法返回树中最右边的值。这怎么样?我不确定我是否完全理解折叠,但我认为折叠的重点是对树中的每个元素进行一些操作。如何使用它只返回树的最右边的值?

我也不确定如何调用该方法。我一直遇到未指定参数类型的问题。有人能告诉我调用这个fold_tree方法的正确方法吗?

2 个答案:

答案 0 :(得分:5)

  

这将如何运作?我不确定我完全理解弃牌

您的foldTree方法正在做的是递归地走树,将自己应用于它遇到的每个NodeLeaf。该方法还有两个需要应用的类型参数,AB,具体取决于提供的树的类型。

为了示例,我们假设Tree[Int]定义如下:

val n = Node(1, Leaf(2), Node(3, Leaf(5), Node(4, Leaf(42), Leaf(50))))

树的结构如下所示:

Tree

我们希望获得最合适的值,即50。为了使用foldTree的当前实现,我们需要提供两种方法:

  1. f1: A => B:给定A,投放B
  2. f2: (A, B, B) => B:给定一个A和两个B值,投放B
  3. 我们可以看到f1应用于Leaff2应用于Node(因此为每种方法提供的元素数量不同)。因此,这给了我们一个提示,即我们提供给foldTree的函数将分别应用于每个函数。

    在我们的树下,充满了这些知识:

    val n = Node(1, Leaf(2), Node(3, Leaf(55), Node(4, Leaf(42), Leaf(50))))
    

    我们提供以下方法:

    println(foldTree[Int, Int](identity)((x, y, z) => z)(n))
    

    这意味着如下:

    1. 如果我们遇到Leaf节点并在其上进行映射(通过在其上应用f1),我们只想提取它的值。
    2. 遇到Node元素(并对其应用f2)时,我们希望采用最右边的元素,这是由第三个元素{{1在我们的方法中。
    3. 运行此项,产生预期结果:z

      如果我们想要针对任何50进行一般性扩展,我们可以说:

      A

答案 1 :(得分:0)

fold_tree[A,A](identity)((_,_,z) => z)(t)

这应该有效,因为该方法接受类型A并返回类型A.它告诉方法我们是否在叶子,只返回叶子值。如果我们有一个节点,一个左树和一个右树,则返回正确的树的值。