我正在执行确定树是否平衡的功能。
fun balanced(tree) =
let
fun size tree =
case tree of
Lf => 0
| Br(xs,ys,zs) => 1 + size ys + size zs
fun depth tree =
case tree of
Lf => 0
| Br(xs,ys,zs) =>
let val l_count = 1 + depth ys
val r_count = 1+ depth zs
in
if l_count > r_count then l_count else r_count
end
in
if size(ys) = size(zs) andalso depth(ys) = depth(zs) then true
else if tree=Lf then true
else false
end;
但是会产生以下错误:
stdIn:829.18-829.20 Error: unbound variable or constructor: zs
stdIn:829.9-829.11 Error: unbound variable or constructor: ys
stdIn:829.48-829.50 Error: unbound variable or constructor: zs
stdIn:829.36-829.38 Error: unbound variable or constructor: ys
答案 0 :(得分:2)
in
和end
之间
in
if size(ys) = size(zs) andalso depth(ys) = depth(zs) then true
else if tree=Lf then true
else false
end;
您使用从未定义的ys
和zs
。您在ys
和zs
函数中拥有的depth
和size
在这些函数中是本地的,而对balanced
不可见。
答案 1 :(得分:1)
您尚未提供此函数所依据的数据类型。我认为它看起来像这样:
datatype 'a binary_tree = Lf | Br of 'a * 'a binary_tree * 'a binary_tree
由于代码,您会收到未绑定变量错误
if size(ys) = size(zs) andalso ...
在其范围内没有此类变量。这些变量仅在您的辅助函数范围内可用。这里有一些提示:
当xs
实际上是位于分支和ys
中的值时,不要命名变量zs
,xs
和ys
和zs
实际上是分支的左和右子树。更好的名称可以是x
(如果不使用,则为_
),left
和right
。
使用Int.max (x, y)
代替if x > y then x else y
。
类似地,if foo then true else false
等效于foo
。
因此,balanced
正文中不需要if-then-else。
直接在函数参数中执行模式匹配。
不必知道子树(size
)中的元素数来确定它是否平衡。只需知道树的高度/深度(depth
)。
将帮助器功能移出该功能。
它们本身很有用。
fun size Lf = 0
| size (Br (_, left, right)) = 1 + size left + size right
fun depth Lf = 0
| depth (Br (_, left, right)) = 1 + Int.max (depth left, depth right)
在declarative way中写入balanced
:空树(Lf
)是微不足道的。如果左子树平衡,右子树平衡,并且左子树和右子树的深度之差不大于,则非空树(Br ...
)被平衡。 1。
fun balanced Lf = true
| balanced (Br (_, left, right)) =
balanced left andalso
balanced right andalso
...the 'abs'(olute) difference of 'depth left' and 'depth right' is not more than 1...
此解决方案遍历了很多树:首先使用balanced
,然后使用 使用depth
。您可以通过返回一个元组(is_subtree_balanced, subtree_height)
来编写仅遍历树一次的解决方案。
fun balanced_helper Lf = (true, 0)
| balanced_helper (Br (_, left, right)) =
let val (is_left_balanced, left_height) = balanced_helper left
in ...we can stop here if the left sub-tree isn't balanced...
let val (is_right_balanced, right_height) = balanced_helper right
in ...we can stop here if the right sub-tree isn't balanced...
...otherwise: (true, 1 + Int.max(left_height, right_height))...
end
end
fun balanced tree = #1 (balanced_helper tree)