我有一个由
代表的树type LazyTree<'T> =
| LazyBranch of 'T * ('T LazyTree list Lazy)
我想为每个节点分配一个数字n
,从左到右计数。
更正式
编辑:
对于节点a
,如果h(a)=0
没有子节点,则a
对于父a
,p
h(a)=h(p+1)
对于没有父级的节点a
,L(a)
是空集。
对于具有父级的节点a
,L(a)
是一组所有节点,对于每个节点i
,从根到它的路径不包含{ {1}}
对于节点a
,a
是S(a)
的所有元素,其中每个元素L(a)
都包含i
我需要将每个节点h(i)<=h(a)
的值替换为a
我不能为我的问题找到一个不涉及副作用的解决方案。
我的功能应该返回一棵树。
它的节点依赖于左兄弟节点。因此,该函数应该以{{1}}作为参数。
但它最左边的孩子依赖于我们最右边的兄弟姐妹,这依赖于我们。看来,我们有一个无限循环。
我不会问如何在有限树上解决它。
我不是在问一个抽象的概念。 以下是如何从另一个树中返回一个无限树:
S(a)
答案 0 :(得分:1)
你说这里所需的递归结构有点错综复杂。这是一种方法。我将使用辅助函数number
,该函数对给定前一个编号树的树列表以及此列表与此列表中第一个树的第一个子树之间的所有编号树进行编号。然后,如果列表非空:
很抱歉,如果此说明没有启发性,但绘制图片可能有所帮助。无论如何,这是相应的代码:
// These help with type inference
let value (LazyBranch(v,_)) = v
let children (LazyBranch(_,ts)) = ts.Value
let numberedTree =
let rec number prev between = function
| [] -> []
| t::ts ->
let rec rest = number first (seq { yield! between; yield! children first }) ts
and first =
let between' = seq { yield! rest; yield! between }
LazyBranch(value prev + 1, lazy (children t |> number (defaultArg (Seq.tryLast between') first) (between' |> Seq.collect children)))
first::rest
fun t ->
let rec result = LazyBranch(0, lazy number result [] (children t))
result
答案 1 :(得分:-2)
分配这样的数字是不可能的,因为它需要(非懒惰)遍历无限树。 你需要的是广度优先遍历,就像在这个伪代码中一样:
let traverse (node:LazyTree<'T>) =
let q = System.Collections.Generic.Queue()
q.Enqueue node
let mutable i = 0
while 0 < q.Count do // always TRUE
let node = q.Dequeue ()
printfn "Node #%i: %A" i node.Map
i <- i + 1
for child in node.Children.Force() do
q.Enqueue child