使用OCaml中的数据结构的正确方法(The right way to use a data str

2019-07-18 11:53发布

好吧,我已经写了binary search tree OCaml中。

type 'a bstree = 
    |Node of 'a * 'a bstree * 'a bstree
    |Leaf


let rec insert x = function
    |Leaf -> Node (x, Leaf, Leaf)
    |Node (y, left, right) as node -> 
        if x < y then
            Node (y, insert x left, right)
        else if x > y then
            Node (y, left, insert x right)
        else
            node

我想上面的代码没有问题。

当使用它,我写的

let root = insert 4 Leaf

let root = insert 5 root

...

这是正确的方式use/insert到树?

我的意思是,我想我不应该申报的根源,每次我再次更改变量根的价值,正确的时间?

如果是这样,我怎么能始终保持一个根,可以在任何时间值插入树?

Answer 1:

这看起来像插入到树良好的功能代码。 它插入过程中不发生变异的树,而是它创建一个包含值的新树。 不可改变的数据的基本想法是,你不“养”的事情。 你计算值,并通过他们对新的功能。 例如,下面是一个创建从列表树的功能:

let tree_of_list l = List.fold_right insert l Leaf

它通过使电流沿着树为每个新调用insert

这是值得我们学习有这样的想法,因为许多计划生育的好处从使用不可变数据的导出。 然而,OCaml的是混合范式语言。 如果你愿意,你可以使用一个参考(或可变的记录字段)“养”一棵树,因为它的变化值,就像在普通的命令式编程。

编辑:

你可能会认为下一届会议显示了一个变量x的修改:

# let x = 2;;
val x : int = 2
# let x = 3;;
val x : int = 3
# 

然而,看看这个方式是,这些都是发生在这两个被命名为X两个不同的值。 因为名字相同,x的旧值是隐藏的。 但是,如果你有另外的方式来访问旧值,这将仍然存在。 也许下面将展示如何工作:

# let x = 2;;
val x : int = 2
# let f () = x + 5;;
val f : unit -> int = <fun>
# f ();;
- : int = 7
# let x = 8;;
val x : int = 8
# f ();;
- : int = 7
# 

创建一个名为新事物x具有值8,不影响什么f一样。 它仍然使用相同的旧x它被定义时存在。

编辑2:

从树中删除值不可改变类似于增加一个值。 也就是说,你实际上并没有修改现有的树。 您创建一个不说你不希望值的新树。 正如插入不会复制整个树(它重新使用以前的树的大部分地区),所以删除也不会复制整个树。 在新的树都没有改变树的任何部分可以被重新使用。

编辑3

下面是一些代码从树中删除的值。 它使用邻接其已知是不相交的(在此外,所有的值都小于b中的所有值)两棵树一个辅助函数:

let rec adjoin a b =
    match a, b with
    | Leaf, _ -> b
    | _, Leaf -> a
    | Node (v, al, ar), _ -> Node (v, al, adjoin ar b)

let rec delete x = function
    | Leaf -> Leaf
    | Node (v, l, r) ->
        if x = v then adjoin l r
        else if x < v then Node (v, delete x l, r)
        else Node (v, l, delete x r)

(希望我不只是破坏你的家庭作业!)



文章来源: The right way to use a data structure in OCaml