好吧,我已经写了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
到树?
我的意思是,我想我不应该申报的根源,每次我再次更改变量根的价值,正确的时间?
如果是这样,我怎么能始终保持一个根,可以在任何时间值插入树?
这看起来像插入到树良好的功能代码。 它插入过程中不发生变异的树,而是它创建一个包含值的新树。 不可改变的数据的基本想法是,你不“养”的事情。 你计算值,并通过他们对新的功能。 例如,下面是一个创建从列表树的功能:
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)
(希望我不只是破坏你的家庭作业!)