我得到了以下二叉树的定义
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方法的正确方法吗?
答案 0 :(得分:5)
这将如何运作?我不确定我完全理解弃牌
您的foldTree
方法正在做的是递归地走树,将自己应用于它遇到的每个Node
或Leaf
。该方法还有两个需要应用的类型参数,A
和B
,具体取决于提供的树的类型。
为了示例,我们假设Tree[Int]
定义如下:
val n = Node(1, Leaf(2), Node(3, Leaf(5), Node(4, Leaf(42), Leaf(50))))
树的结构如下所示:
我们希望获得最合适的值,即50。为了使用foldTree
的当前实现,我们需要提供两种方法:
f1: A => B
:给定A
,投放B
值f2: (A, B, B) => B
:给定一个A
和两个B
值,投放B
。我们可以看到f1
应用于Leaf
,f2
应用于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))
这意味着如下:
Leaf
节点并在其上进行映射(通过在其上应用f1
),我们只想提取它的值。Node
元素(并对其应用f2
)时,我们希望采用最右边的元素,这是由第三个元素{{1在我们的方法中。运行此项,产生预期结果:z
。
如果我们想要针对任何50
进行一般性扩展,我们可以说:
A
答案 1 :(得分:0)
fold_tree[A,A](identity)((_,_,z) => z)(t)
这应该有效,因为该方法接受类型A并返回类型A.它告诉方法我们是否在叶子,只返回叶子值。如果我们有一个节点,一个左树和一个右树,则返回正确的树的值。