F#如何镜像二叉树

时间:2018-09-06 21:37:53

标签: f# binary-tree flip

F#的新手 我正在尝试翻转树枝上的子树。

我们必须使用以下数据类型

df = df.set_index('Name1')
df.loc[:, 'Money_1'] = df2.set_index('Name').Money

df = df.reset_index().set_index('Name2')
df.loc[:, 'Money_2'] = df2.set_index('Name').Money

df.reset_index()

示例树

    Name1   Name2   Money_1 Money_2
0   John    Jack    40.0    10.0
1   Eva     Tom     20.0    80.0
2   Eva     Sara    20.0    34.0
3   Carl    Sam     77.0    NaN
4   Sam     Erin    NaN     12.0

到目前为止,这是我的代码:

 type btree = Empty | Node of btree * int * btree
 type finding = NotFound | Found of int

示例输入和输出:

 let s = Node (Node(Empty, 5, Node(Empty, 2, Empty)), 3, Node (Empty, 6, Empty))
 (*
      (3)
     /    \
    (5)   (6)
    / \   |  \
   () (2) () ()
      / \
     () ()
 *)

会返回

 let rec mirror t = function
     | Node(Empty, t, Empty) -> t 
     | Node (t1, t, t2) ->  
     | _ -> failwith "Empty"

现在,代码无法完成任何工作,我需要有关如何移动节点以获取所需镜像树的帮助。

我想知道是否必须实现另一个用于删除/插入节点的功能?任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

镜像意味着将左分支变为右分支,将右分支变为左分支。因此,在您的递归函数中执行此操作。例如,如果您从一个基本的3节点树开始:

   1
2     3

然后将镜像

    1
  3   2

因此在代码中表示:

let rec mirror t = function
     | Node(Empty, t, Empty) -> t 
     | Node (left, value, right) -> Node (right, value, left)

除非这不适用于较大的树木,但这是一个开始。您真正想要的是左右节点的镜像。您应该能够通过在match子句的最后一行的正确位置添加2个对mirror的调用来完成上述功能。

答案 1 :(得分:1)

这似乎是家庭作业,因此在“移交”解决方案之前,我将添加一些学习要点。让我们看看您已经编写的代码,这不是一个糟糕的开始。我将其粘贴在下面以供参考。

let rec mirror t = function
    | Node(Empty, t, Empty) -> t 
    | Node (t1, t, t2) ->  
    | _ -> failwith "Empty"

通过添加rec关键字,开始允许函数递归调用自身。您这样做是对的,实际上这是一个非常重要的认识,执行此任务的方法是创建一个递归函数。因为,实际上,“镜像”一棵树意味着什么?镜像意味着在每个节点上翻转子树的顺序,并镜像每个子树。

这是一个递归定义,因为要镜像节点,则需要镜像子树。因此,添加rec关键字是正确的。但是,在您的代码中,您没有正确处理终端状态Empty。使用btree定义,您最终看到一棵Empty树,这意味着您最终抛出异常(使用{{1} }。这显然不是期望的行为。一棵空树的镜子是什么样的?空!然后,处理这种情况的方法是将failwith替换为| _ -> failwith "Empty"

现在,在F#中,| Empty -> Empty只是let foo = function | ...的语法糖,这意味着您的函数实际上使用了两个参数:let foo <arg> = match <arg> with | ...和一个隐藏的参数由t糖制成。我想这不是您想要的,所以您应该删除当前未使用的参数function,或将t替换为function

参数match t with当前未使用的原因是,t在匹配情况t中反弹到整数节点值。这也意味着编译器当前的最佳猜测是,| Node(..., t, ...)的返回类型应该是mirror,而不是int,因为在第一个返回的是btree情况。

最后一点是,没有理由直接使用空子树处理案件,因为它们也只是int

牢记上述所有内容,我希望我的解决方案是合理的

btree