使用OCAML中提供的高阶函数检查树是否为BST

时间:2015-09-24 11:43:03

标签: functional-programming ocaml binary-search-tree higher-order-functions

所以让我首先说这是过去的作业的一部分,我无法解决,但在我准备测试时,我想知道如何做到这一点。我有教师提供的map_tree和fold_tree的这些实现:

let rec map_tree (f:'a -> 'b) (t:'a tree) : 'b tree =
match t with
| Leaf x -> Leaf (f x)
| Node (x,lt,rt) -> Node (f x,(map_tree f lt),(map_tree f rt))

let fold_tree (f1:'a->'b) (f2:'a->'b->'b->'b) (t:'a tree) : 'b =
  let rec aux t =
    match t with
     | Leaf x -> f1 x
     | Node (x,lt,rt) -> f2 x (aux lt) (aux rt) 
  in aux t

我需要使用上述功能实现一个验证树是BST的函数,到目前为止,这是我已经完成的并且我得到了错误:

 Error: This expression has type bool but an expression was expected of type
     'a tree

这是我的代码:

 let rec smaller_than t n : bool =
 begin match t with
 | Leaf x -> true
 | Node(x,lt,rt) -> (x<n) && (smaller_than lt x) && (smaller_than rt x)
 end

 let rec greater_equal_than t n : bool =
 begin match t with
 | Leaf x -> true
 | Node(x,lt,rt) -> (x>=n) && (greater_equal_than lt x) && (greater_equal_than rt x)
 end

 let check_bst t =
 fold_tree (fun x -> true) (fun x lt rt -> ((check_bst lt) && (check_bst rt)&&(smaller_than lt x)&&(greater_equal_than rt x))) t;;

有什么建议吗?我似乎无法准确理解更高阶函数在OCAML中的工作原理

1 个答案:

答案 0 :(得分:6)

BST的规格是什么?它是二叉树,其中:

  • 左子树中的所有元素(也是BST)严格小于节点上存储的值
  • 并且右子树中的所有内容(也是BST)大于或等于节点上存储的值

A fold是一个归纳原则:您必须解释如何处理基本情况(此处为Leaf情况)以及如何在步骤情况下组合子结果的结果(这里有Node个案例。)

Leaf始终为BST,因此基本情况非​​常简单。但是,在Node情况下,我们需要确保值在正确的子树中。为了能够执行此检查,我们将需要额外的信息。我们的想法是fold计算:

  • 给定树是否为BST
  • 及其所有值存在的时间间隔

让我们引入类型同义词来构建我们的想法:

type is_bst      = bool
type 'a interval = 'a * 'a

正如预测的那样,基本情况很简单:

let leaf_bst (a : 'a) : is_bst * 'a interval = (true, (a, a))

Node案例中,我们在节点处存储了值a,并且左侧(lih)递归计算结果,如l eft {{1 }} nduction i ypothesis)和右子树。这样构建的树是h当且仅当两个子树是(BST)并且它们的值尊重前面描述的属性时。此新树的值所处的时间间隔现在更大b1 && b2

(lb1, ub2)

最后,检查树是否为let node_bst (a : 'a) (lih : is_bst * 'a interval) (rih : is_bst * 'a interval) = let (b1, (lb1, ub1)) = lih in let (b2, (lb2, ub2)) = rih in (b1 && b2 && ub1 < a && a <= lb2, (lb1, ub2)) 的函数是通过从其上调用BST的结果中弹出布尔值来定义的。

fold_tree leaf_bst node_bst