简体   繁体   中英

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:

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?

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?

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?

Yes. If you balance the tree properly (eg Red-Black trees) then this means insertion is 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?

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. 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. (His thesis covers most of the same content and is freely available.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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