我正在尝试创建一个打印二叉树的函数。我的二叉树数据类型如下所示:
datatype 'a BT = empty | bTree of 'a * 'a BT * 'a BT;
我还创建了一个打印整数的函数,我将用于节点:
fun printInt n = print (Int.toString n);
正如你所看到的,BT数据类型有3个节点('a,'一个BT,'一个BT),我已经开始制作一个displayTree函数,但是找不到打印出我的printInt函数的单位类型的方法回报。我确信还有其他方法可以做到这一点,但在这种情况下,我将如何返回三个连接的单元类型。这是我到目前为止(我明白@s是不正确的)。
fun displayTree T =
let
val bTree (root, left, right) = T;
in
(printInt root)@ (displayTree left) @ (displayTree right)
end;
我并不担心树的行格式化。我只是不确定如何将我的(printInt root)附加到递归调用。
编辑:
我希望displayTree函数是多态的
答案 0 :(得分:1)
您必须进行一些更改才能使此代码正常工作:
将树定义更改为:
datatype btree =
Empty |
Node of int * btree * btree;
printInt
函数是简短的,所以在这种情况下我会避免它:
fun displayTree T =
case T of
Empty => ""
|Node(root, left, right) => (Int.toString root) ^ (displayTree left) ^ (displayTree right)
请注意,此函数返回表示树的字符串,因此您可以在需要时打印它。字符串连接由@
表示。你在函数中缺少的秘密成分称为“模式匹配”。在这种情况下,您可以避免使用if语句进行模式匹配。
让我们先制作一个多态类型:
datatype 'a btree =
Empty |
Node of 'a * 'a btree * 'a btree
让这个函数变成多态:
fun displayTree T f =
case T of
Empty => ""
|Node(root, left, right) => (f root) ^ (displayTree left f ) ^ (displayTree right f )
现在你必须定义将你的匿名类型转换为string
的函数f。
让我们更进一步,定义相同的函数,返回可以打印的节点值列表:
fun displayTree T f =
case T of
Empty => [""]
|Node(root, left, right) => [f root] @ (displayTree left f) @ (displayTree right f)
您可以将其转为返回unit
s的列表a:
fun displayTree T f =
case T of
Empty => [print ""]
|Node(root, left, right) => [print(f root)] @ displayTree left f @ displayTree right f
但我不明白你打算怎么处理它们。
答案 1 :(得分:1)
您的代码存在一些问题,因此很难知道从哪里开始。如果您希望 printInt 实际打印节点的值并返回 unit ,那么您不希望对结果执行任何操作。您应该简单地丢弃它,并且呼叫应该看起来像
(printInt root; displayTree left; displayTree right)
您可能不需要 let..in..end 块中的括号,但需要分号。
其他问题是您需要在树上进行模式匹配。另外,通过在 displayTree 的主体中包含 printInt ,您只能打印 int bTree 类型的值。如果希望 displayTree 是多态的,则需要传入一个函数来打印节点,因为它取决于节点的类型。如果节点是整数,则传入的函数可以是 printInt ,但对于不同类型的节点则是其他的。