Stack_overflow与树遍历

时间:2013-07-11 12:28:56

标签: recursion tree functional-programming ocaml

我的树定义如下:(这只是为了更好地理解,我的数据类型要复杂得多。)

  type tree = {
    mutable value : int;
    mutable nodes : tree list
  }

我需要找到0和1的序列,如下所示:

    1  
    |
  0 0
  \ /
   1
   |
   1

输出将是根和0和1的序列。这是我的代码:(我假设序列仅在树的节点(树列表)具有值0时才出现一个元素,但我需要改变它,因为它没有必要。)

let rec getSequence tree = 
  match tree.value with
  | 0 ->
if (List.length tree.nodes) = 1 then
  let nextTree = List.hd tree.nodes in
  match nextTree.value with
  | 1 -> 
    nextTree.nodes <- [];
    tree.nodes <- [nextTree];
    [tree]
  | 0 -> List.concat (List.map (fun t -> getSequence t) nextTree.nodes)
else List.concat (List.map (fun t -> getSequence t) tree.nodes)
  | 1 -> List.concat (List.map (fun t -> getSequence t) tree.nodes)

出于某种原因,当我执行代码时,会引发异常Stack_overflow。有人可以帮帮我吗?

2 个答案:

答案 0 :(得分:0)

let nextTree = List.hd tree.nodes in
nextTree.nodes <- [];

不等同于:

tree.nodes<-(List.tl tree.nodes);

对于第一个,树不会更改它包含的列表,因此您始终执行相同的操作并且您有一个stack_overflow

答案 1 :(得分:0)

我尝试过但你的样本输入也没有例外。我猜你只能通过更大(特别是更深)的输入获得Stack_overflow异常。

以下是一些选项:

  1. 增加堆栈大小:

    导出OCAMLRUNPARAM ='l = 64M'#或其他

  2. 将函数重写为尾递归,因此不需要很多堆栈空间。您可以通过将状态作为参数传递来实现。

  3. 其他建议:

    • 使用模式匹配代替List.lengthList.hd
    • 如果你选择2.,你也可以避免使用List.concat
相关问题