简体   繁体   English

协助在 SML 中使用二叉树

[英]Assistance working with Binary Trees in SML

I'm new to SML and would like some assistance in using the following implementation of a binary tree.我是 SML 的新手,希望在使用以下二叉树实现方面获得一些帮助。

datatype tree = NODE of int * tree * tree | LEAF of int;

I see that the tree is defined by either nodes which has two sub-trees or a LEAF with an integer.我看到树是由具有两个子树的节点或具有 integer 的 LEAF 定义的。

How can I access the subtrees so that I can determine the maximum, the minimum, and if the element is present in the tree?如何访问子树以便确定最大值、最小值以及元素是否存在于树中?

What is the process of accessing either the left and right sub-trees?访问左右子树的过程是什么?

What is the process of accessing either the left and right sub-trees?访问左右子树的过程是什么?

You use pattern matching:您使用模式匹配:

fun goLeft (NODE (_, l, _)) = l
  | goLeft LEAF = raise Fail "Cannot go left here!"

fun goRight (NODE (_, _, r)) = r
  | goRight LEAF = raise Fail "Cannot go right here!"

How can I [...] determine the maximum, the minimum, and if the element is present in the tree?我如何[...]确定最大值、最小值以及元素是否存在于树中?

You build recursive functions that pattern match on sub-trees.您构建在子树上进行模式匹配的递归函数。

For example, there is no invariant in a binary tree that says that the minimal element has a fixed, known location in the tree.例如,二叉树中没有不变量表示最小元素在树中具有固定的已知位置。 But this invariant is present in a binary search tree, in which all elements in every left sub-tree (including the root) are made sure to be less than or equal to all the elements of their right sub-trees.但是这个不变量存在于二叉搜索树中,其中每个左子树(包括根)中的所有元素都确保小于或等于其右子树的所有元素。

The tree那个树

    5
   / \
  3   8
 /   / \
2   7   9

qualifies as a binary search tree because this invariant holds.有资格作为二叉搜索树,因为这个不变量成立。

Finding the minimal element in such a tree means recursing in such a way that you always pick the left sub-tree until there is no left sub-tree, in which case you have found the minimum.在这样的树中找到最小元素意味着以这样一种方式递归,即你总是选择左子树,直到没有左子树,在这种情况下你找到了最小值。 How do you know when to stop recursion?你怎么知道什么时候停止递归?

fun goLeeeft (NODE (_, l, _)) = goLeeeft l
  | goLeeeft LEAF = "I've gone all the way left, but I have nothing to show for it."

fun minimum (NODE (x, l, r)) = (* is this the last non-leaf node? *)
  | minimum LEAF = raise Empty (* whoops, we recursed too far! *)

When you pattern match one level deep, that is, on NODE (x, l, r) , you only know that this is a non-leaf node, but you don't know the exact value located in the node, x , and you don't know anything about the sub-structure of this node's left and right sub-trees.当您模式匹配一个深度级别时,即在NODE (x, l, r)上,您只知道这是一个非叶节点,但您不知道位于节点x中的确切值,并且你对这个节点的左右子树的子结构一无所知。

You could go two ways here: Either make a helper function that tells you when to stop recursing, or pattern match one level deeper into l .你可以在这里用两种方法 go :要么制作一个帮助器 function 告诉你何时停止递归,要么模式匹配更深一层l Here are two examples of that;这里有两个例子; they perform the same thing:他们执行相同的操作:

(* Using a helper function *)
fun isLeaf (NODE (_, _, _)) = false
  | isLeaf LEAF = true

fun minimum (NODE (x, l, _)) =
      if isLeaf l
      then x
      else minimum l
  | minimum LEAF = raise Empty

(* Using direct pattern matching *)
fun minimum (NODE (x, LEAF, _)) = x
  | minimum (NODE (x, l, _)) = minimum l
  | minimum LEAF = raise Empty

Now maximum writes itself.现在maximum写自己。

As a curiosity, you can define generic recursion schemes such as folding on trees:Sml folding a tree出于好奇,您可以定义通用递归方案,例如在树上折叠:Sml fold a tree

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM