【问题标题】:Defining Tree's and Search Function定义树和搜索功能
【发布时间】:2018-07-30 10:12:44
【问题描述】:

我正在尝试定义我的树并创建一个搜索功能,但我想我迷失在 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 中,我认为我不了解如何编写多层树。

【问题讨论】:

  • 你不是在问问题。
  • 我的问题是为什么我的 T2 实现不能与 T1 的搜索功能一起使用。以及为什么 T2 在声明中有 #。我将对其进行编辑以使其更清晰@SimonShine
  • 你知道为什么我的T2在搜索功能中不能正常工作吗?它只能为树的头部读取 true,并且每个其他数字输入都会返回错误。 @SimonShine

标签: search tree sml smlnj


【解决方案1】:
  • if ... then ... else true有点多余;通常您可能会改用惰性二元运算符 orelseandalso,但是当您特别感兴趣的是某事物是 lessequal 还是 greater ,使用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
    

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

    由于您的 eitherTrees 可以同时包含字符串和整数,并且您的函数 eitherSearch 显式查找整数,您需要指定它应该如何处理字符串。似乎您假设只要节点包含整数, eitherTrees 就被排序为二叉搜索树,但是当它们包含字符串时会发生什么?然后您必须假设结果可能在任一子树中吗?

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

    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?

【讨论】:

  • 感谢您的建议,非常感谢。我会继续努力让这棵树工作。再次感谢您花时间查看它。
猜你喜欢
  • 1970-01-01
  • 2020-06-21
  • 2019-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
  • 1970-01-01
  • 2022-11-15
相关资源
最近更新 更多