Tree 标记二叉树的叶子

Tree 标记二叉树的叶子,tree,functional-programming,ocaml,Tree,Functional Programming,Ocaml,我试图用从零开始递增的数字来标记二叉树的叶子。这是我对二叉树的定义 type btree = I of int | Node of string * btree * btree 应用My函数时,应使用从最左边的叶子开始的数字标记树叶,标记为零。例如,节点(“a”、节点(“b”、i25、i54)、节点(“c”、i12、i47”)应返回树节点(“a”、节点(“b”、i0、i1)、节点(“c”、i2、i3”)。我该怎么做? 我试图编写代码,但没有给出合适的结果。这是我的密码: let mark

我试图用从零开始递增的数字来标记二叉树的叶子。这是我对二叉树的定义

  type btree = I of int | Node of string * btree * btree
应用My函数时,应使用从最左边的叶子开始的数字标记树叶,标记为零。例如,节点(“a”、节点(“b”、i25、i54)、节点(“c”、i12、i47”)应返回树节点(“a”、节点(“b”、i0、i1)、节点(“c”、i2、i3”)。我该怎么做? 我试图编写代码,但没有给出合适的结果。这是我的密码:

 let mark bst =
  let number x = function
  |Node(a, I b, I c) -> Node(a, I x, I (x + 1))
  |Node(a, b, I c) -> Node(a, (number x b), I(x + 1))
  |Node(a, I b, c) -> Node(a, x, (number (x + 1) c)
  |Node(a, b, c) -> Node(a, (number x b), (number x c))
 in number 0 bst
这段代码编译得很好,但从一开始就对左子树和右子树分别编号,即0。
请帮忙

以下方法应该有效。它一个接一个地处理子树

let mark bst = 
  let rec number = function
    | (x, I a) -> (x+1, I x)
    | (x, Node(a, b, c)) -> 
    let p1 = number (x,b) in
    let p2 = number ((fst p1),c) in
    ((fst p2),Node(a,(snd p1), (snd p2)))
  in snd (number (0,bst))
下面是我在您的示例上运行它时得到的结果。老实说,这是我唯一尝试过的例子

# let tr =  Node("a", Node("b", I 25, I 54), Node("c", I 12, I 47));;
val tr : btree = Node ("a", Node ("b", I 25, I 54), Node ("c", I 12, I 47))
# markit tr;;
- : btree = Node ("a", Node ("b", I 0, I 1), Node ("c", I 2, I 3))
代码说明: 要以从左到右的升序唯一地标记每个叶,您必须查看每个子树,一次一个。在查看左子树之后,您需要知道在标记过程中已经走了多远,即下一个标签是什么。为了获得这种能力,我的函数
number
返回一对类型
int*btree
,而你的函数返回一对类型
btree
。该对中的
int
是下一个未使用的标签。返回一对,允许我们有两个返回值。聪明

我想您理解前两行,因为它们与您的完全相同(几乎-记住在定义递归函数时使用
let rec
)。在函数
mark
中,
number
函数在最后一行启动,就像在代码中一样。区别在于,我没有像你那样给函数两个输入值,而是给它一个;一对值。不过,最后,我们想要的只是该对中的第二个条目,我们使用
snd
提取该条目。在第3-4行中,我们检查是查看整数还是节点(即叶或子树)。请注意,根据您的类型定义,这两种情况是唯一的可能性。如果我们在看一个节点,我们需要首先遍历左子树,这发生在第5行。在遍历righ子树之后,我们仍然需要将下一个未使用的标签传递给父节点,这就是为什么我们需要第6行。在第7行中,组装回路对


哇。这变得相当漫长。但我希望它能澄清一些事情。如果没有,请再次询问

顺便说一句,如果您不确定代码中发生了什么,请随时询问。不确定代码中发生了什么!!不过,它在所有示例中都有效:)很高兴听到它按预期工作!我对我的回答加了一个解释,因为它不适合作为评论很好的解释。唯一的问题是我不知道函数“fst”和“snd”做什么?请详细解释这很容易解释。它们可以应用于配对,是“第一”和“第二”的缩写。假设您正在考虑一对
(a,b)
。然后
fst(a,b)
a
,而
snd(a,b)
b