如何以 O(n) 的时间复杂度将树转换为 SML 中的列表?

问题描述

列表需要是有序遍历。这是我到目前为止所拥有的:

datatype tree =
   Empty 
 | Node of (tree * int * tree)

fun combine (t1 : tree,t2 : tree) : tree =
    case t1 of
      Empty => t2
    | Node(l1,x1,r1) => Node(combine(l1,r1),t2)

fun TTL (t : tree) : int list =
   let val tree = combine(t,Empty) in
      case tree of
         Empty => []
       | Node(l,x,r) => x :: TTL(l)
   end

这不会以正确的顺序输出列表,我现在很困惑。请帮忙。

解决方法

遍历右子树,然后将节点的值附加到该列表,然后遍历左子树,同时向第二个列表添加元素。
您可以使用带有累积参数的辅助函数来完成此操作,

fun TTL t =
    let fun TTL' Empty ns = ns
          | TTL' (Node(l,x,r)) ns = TTL' l (x::TTL' r ns)
    in
        TTL' t []
    end
,

@molbdnilo 发布的答案有效,但进一步的建议不能很好地格式化为评论。利用 SML 的模式匹配功能、类型推断和泛型类型。

您有一个组合功能:

fun combine (t1 : tree,t2 : tree) : tree =
    case t1 of
      Empty => t2
    | Node(l1,x1,r1) => Node(combine(l1,r1),t2)

让我们先去掉不必要的类型注释:

fun combine (t1,t2) =
    case t1 of
      Empty => t2
    | Node(l1,t2)

现在,case ... of 也不是必需的,因为在这种情况下我们可以直接在函数的参数列表中进行模式匹配。

fun combine (Empty,t2) = t2
  | combine (Node(l1,t2) = Node(combine(l1,t2)

最后,您的 tree 类型没有理由只需要在 int 上工作。

datatype 'a tree = Empty | Node of ('a tree * 'a * 'a tree)

希望随着您深入学习,其中一些技巧有助于使您的代码更易于推理和更灵活。