简体   繁体   English

Ocaml - 构建二叉树

[英]Ocaml - building binary trees

I'm reading tutorial for OCaml by Jason Hickey and here is in short the proposed way of building a tree: 我正在阅读Jason Hickey的OCaml教程,简而言之就是建议树的建议方法:

type 'a elem = Empty | Node of 'a * 'a elem * 'a elem;;

let rec insert x = function
    | Empty -> Node (x, Empty, Empty)
    | 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;;

Do I understand correctly that this approach makes a copy of the part of the tree where new element is inserted and attaches part of the old tree to this new copy? 我是否正确理解这种方法是否会复制树中插入新元素的部分,并将旧树的一部分附加到此新副本中?

If so, is my assessment that each insertion creates only O(height(tree)) nodes proper? 如果是这样,我的评估是每次插入只创建O(height(tree))节点吗?

Does this (bit unusual to me) method rely on fact that if inserting many values one-by-one, all older copies of groups of nodes would be efficiently deleted by GC? 这(对我来说有点不寻常)方法是否依赖于以下事实:如果逐个插入多个值,那么GC的所有旧节点副本都将被有效删除?

Do I understand correctly that this approach makes a copy of the part of the tree where new element is inserted and attaches part of the old tree to this new copy? 我是否正确理解这种方法是否会复制树中插入新元素的部分,并将旧树的一部分附加到此新副本中?

If so, is my assessment that each insertion creates only O(height(tree)) nodes proper? 如果是这样,我的评估是每次插入只创建O(高度(树))节点吗?

Yes. 是。 If you balance the tree properly (eg Red-Black trees) then this means insertion is O(log(n)). 如果你正确平衡树(例如红黑树),那么这意味着插入是O(log(n))。

Does this (bit unusual to me) method rely on fact that if inserting many values one-by-one, all older copies of groups of nodes would be efficiently deleted by GC? 这(对我来说有点不寻常)方法是否依赖于以下事实:如果逐个插入多个值,那么GC的所有旧节点副本都将被有效删除?

Yes. 是。 Functional programming languages typically produce a lot of short-lived garbage, eg tuples, closures, and small data type values. 函数式编程语言通常会产生大量短期垃圾,例如元组,闭包和小数据类型值。 But implementations are optimised to make this very cheap (eg via a light-weight heap representation, pointer-bump allocation, and generational collection). 但是实现被优化以使其非常便宜(例如,通过轻量级堆表示,指针碰撞分配和分代收集)。

Note also that there is one fundamental advantage with this approach: functional data structures are automatically persistent , ie the old version stays valid, and multiple versions of a data structure can be used at the same time. 另请注意,此方法有一个基本优势:功能数据结构是自动持久的 ,即旧版本保持有效,并且可以同时使用多个版本的数据结构。 With imperative data structures you have two options when you need to "restore" an old version: (1) copying the whole structure beforehand, or (2) maintaining a change log and run that backwards. 使用命令式数据结构,当您需要“恢复”旧版本时,您有两个选项:(1)预先复制整个结构,或(2)维护更改日志并向后运行。 Both options are often more expensive than using a functional structure, where persistence comes for free. 这两种选择通常比使用功能结构更昂贵,其中持久性是免费的。

See Chris Okasaki's excellent book on Purely Functional Data Structures for a detailed discussion of complexity, amortised costs and various other aspects of various functional data structures. 有关复杂性,摊销成本和各种功能数据结构的各种其他方面的详细讨论,请参阅Chris Okasaki关于纯功能数据结构的优秀书籍。 (His thesis covers most of the same content and is freely available.) (他的论文涵盖了大部分相同的内容,并且是免费提供的。)

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

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