定义树和搜索功能

时间:2018-02-20 05:48:52

标签: search tree sml smlnj

我正在尝试定义我的树并创建一个搜索功能,但我认为我迷失在SML的语法中。这是我的树

datatype either = ImAString of string | ImAnInt of int;
datatype eitherTree = Empty
                    | eLEAF of either 
                    | eINTERIOR of (either*eitherTree*eitherTree);

这是我的搜索功能

fun eitherSearch (eLEAF(v)) x = false
  | eitherSearch (eINTERIOR(ImAnInt(v), lt, rt)) x =
    if x < v then eitherSearch lt v
    else if x > v then eitherSearch rt v
    else true;

这就是我定义树的方式

val T2 = eINTERIOR(ImAnInt(4), eLEAF(ImAnInt(1), eLEAF(ImAnInt(2), Empty, Empty), Empty), eINTERIOR(ImAnInt(3), Empty, Empty));

返回

val T2 =
  eINTERIOR
    (ImAnInt 4,eINTERIOR (ImAnInt #,eINTERIOR #,Empty),
     eINTERIOR (ImAnInt #,Empty,Empty)) : eitherTree

我猜这是不正确的,因为那些#符号没有意义。有没有更好的方法来定义树,以便它在搜索功能中工作?当我定义一个像

这样的小树时
val T1 = eINTERIOR(ImAnInt(5), eLEAF(ImAnInt(4)), eLEAF(ImAnInt(6)));

搜索功能正常,但在T2中,我不认为我理解如何编写多层树。

1 个答案:

答案 0 :(得分:1)

  • 执行if ... then ... else true略显多余;通常你可能会使用惰性二元运算符orelseandalso,但当你特别感兴趣的是 less 相等 >或更多,请使用Int.compare

    if x < v then eitherSearch lt v
    else if x > v then eitherSearch rt v
    else true;
    

    变为:

    case Int.compare (x, v) of
         EQUAL   => true
       | LESS    => eitherSearch lt v
       | GREATER => eitherSearch rt v
    
  • 你的树上不需要三个构造函数; EmptyeLEAFeINTERIOR,因为您可以以不同的方式创建同一棵树;这将使得对它们进行递归的函数变得更加复杂。例如,以下值是等效的:

    val t1 = eINTERIOR (ImAnInt 42, Empty, Empty)
    val t2 = eLEAF (ImAnInt 42)
    

    更简单的二叉树定义可能如下所示:

    fun eitherTree = Empty | Interior of either * eitherTree * eitherTree
    
  • 编译函数eitherSearch时,您可能已注意到警告:

    ! Warning: pattern matching is not exhaustive
    

    查看使用包含ImAString ...值的树运行时会发生什么:

    - eitherSearch (eINTERIOR (ImAString "Hello", Empty, Empty)) 42;;
    ! Uncaught exception:
    ! Match
    

    Empty子树:

    - eitherSearch (eINTERIOR (ImAnInt 41, Empty, Empty)) 42;
    ! Uncaught exception:
    ! Match
    

    理想情况下,函数不应在运行时崩溃。

    由于你的或者可以包含字符串和整数,并且你的函数eitherSearch明确地查找了整数,你需要指定它应该如何处理字符串。似乎你假设或者三个被排序为二进制搜索树,只要节点包含整数,但是当它们包含字符串时会发生什么?那么你必须假设结果可能在子树中吗?

    我不知道如何完成以下内容:

    fun eitherSearch Empty = false
      | eitherSearch (Interior (ImAString s, lt, rt)) = ???
      | eitherSearch (Interior (ImAnInt n, lt, rt)) = ...
    
  • 对于T2,我无法编译它:您正在使用eLEAF但是给它三个参数。也许在您正在测试的版本中,而不是您发布的版本,您 使用eINTERIOR代替。一旦(1)在数据类型定义中只有两个构造函数,并且(2)覆盖eitherSearch中的所有模式,这个问题就会消失。

How do I ask and answer homework questions?