它说here:
合并两个二叉树的最简单方法是迭代迭代 留下一棵树的孩子,直到到达没有左孩子的节点。 然后将另一棵树的根添加为左子。
易。在"普通代码"中,我写了这样的东西:
if(!left.isEmpty)
thisFuncAgain()
else left = otherSet; return this
然而,我无法想象Scala会如何看待它。以下是我的一些想法。此函数将放在BinaryTree
类:
def merg(that: BinaryTree): BinaryTree = {
if(leftNode.isEmpty) leftNode += that; leftNode
else merg(leftNode)
}
但是,无法重新分配到val
。我可以为左节点递归此函数,但是当它返回时,将不考虑最后一个节点之前的元素。
关于我怎么想到这个的任何提示? 我是Scala的初学者,我真的坚持这一点。
答案 0 :(得分:2)
这取决于BinaryTree
类的外观,而且你没有说清楚。完全可以使用可变BinaryTree
,您可以在其中修改节点。但是这里有一个使用典型的不可变BinaryTree
sealed trait BinaryTree[A] {
def merge(that: BinaryTree[A]): BinaryTree[A]
}
case object Empty extends BinaryTree[Nothing] {
def merge(that: BinaryTree[A]: BinaryTree[A] = that
}
case class Node(left: BinaryTree[A], value: A, right: BinaryTree[A])
extends BinaryTree[A] {
def merge(that: BinaryTree[A]): BinaryTree[A] =
Node(left.merge(that), value, right)
}
它不会修改this
,它会返回BinaryTree
的新实例,并保持this
不变。它并不昂贵,因为that
的所有节点和this
的大多数节点将在两棵树之间共享。需要重新创建的唯一节点位于此根节点及其最左侧节点之间。你获得了不变性的好处,最重要的是它可以自由分享,你永远不需要制作防御性副本。
另一方面,很有可能使左右儿童var
而不是val
并且合并变异原始树。
您在评论中说明它只返回要合并的树。它不是。我刚刚修复了Node.merge中的拼写错误,也许这让你很困惑。 Mabye让你困惑的是,返回通常不是scala。在合并的两个实现中,您可以放置一个返回return that
和return Node(left.merge...
,这意味着完全相同的事情。此外,return Node(...)
与return new Node(...)
相同。无论如何,这是它的工作原理
假设值是整数,this
是
5
/ \
7 C
/ \
2 B
\
A
A
,B
,C
可能是单个节点,整个树木都是空的,我们不在乎,关键是2的左边孩子是空的这是合并的地方。
that
只是M
,因为它包含的内容并不重要。我们走吧。
this
是Node([node 7], 5, C)
我们称之为合并:
Node([node 7], 5, C).merge(M)
返回
Node([node 7].merge(M), 5, C)
关键是此代码不会返回this
。它返回一个新节点,其中左子节点不是原始节点中的节点。它不再是[node 7]
,而是[node 7].merge(M)
。因此,让我们计算[node 7].merge(M)
。 [node 7]
是Node([node 2], 7, B)
。让我们把M合并到那里。
[node 7].merge(M) = Node([node 2], 7, B).merge(M)
= Node([node2].merge(M), 7, B).
同样,在返回的节点中,我们替换了左子节点。再一次:[node2]是Node(Empty,2,A),所以:
[node 2].merge(M) = Node(Empty, 2, A).merge(M)
= Node(Empty.merge(M), 2, A).
现在我们到底了。 Empty.merge(M)
是M
。我们只需要倒带,所有人都会到位。
[node 2].merge(M) = Node(Empty, 2, A).merge(M)
= Node(Empty.merge(M), 2, A)
= Node(M, 2, A)
2
/ \
M A
如你所见,我们实际上已经做了一些事情。结果中M小于2。
又迈进了一步:
[node 7].merge(m) = Node([node 2], 7, B).merge(M)
= Node([Node 2].merge(M), 7, B).
现在我们知道[node2] .merge(M)的含义。所以
Node([node 2], 7, B).merge(M) = Node(Node(M, 2, A), 7, B)
7
/ \
2 B
/ \
M A
我们有[node 7] .merge(m),所以我们可以计算最终结果:
this.merge(m) = Node([node 7].merge(m), 5, C)
我们知道[node 7].merge(m)
是什么,所以最终结果如预期的那样:
5
/ \
7 C
/ \
2 B
/ \
M A