Jackson Tale
Jackson Tale

Reputation: 25812

Deletion in Binary Search Tree in OCaml

i am constructing the operations of binary search tree in OCaml.

type ('a, 'b) bst = 
  | Node of 'a * 'b * ('a, 'b) bst * ('a, 'b) bst
  | Leaf;;

let rec insert k v = function
  | Leaf -> Node (k, v, Leaf, Leaf)
  | Node (k', v', left, right) ->
    if k < k' then Node (k', v', insert k v left, right)
    else if k = k' then Node (k, v, left, right)
    else Node (k', v', left, insert k v right);;

let rec delete k = function
  | Leaf -> Leaf
  | Node (k', v, l, r) as p ->
    if k < k' then Node (k', v, (delete k l),r)
    else if k > k' then Node (k', v, l, (delete k r))
    else 
    match (l, r) with
      | (Leaf, Leaf) -> Leaf
      | (l, Leaf) -> l
      | (Leaf, r) -> r
      | (_, _) ->
        let Node (km, vm, _, _) = max l in
        Node (km, vm, delete km l, Leaf)

Can anyone tell me whether my deletion code is good enough or any improvement?

Upvotes: 1

Views: 4507

Answers (1)

nlucaroni
nlucaroni

Reputation: 47934

One improvement is the case when we insert things that are in the tree, or delete things that are not in the tree. Each of these operations will duplicate the search path to that particular node. Insertion is probably not a problem since you will want to update the value of that key, but deletion would be a case where you can make an improvement. This can be solved by wrapping the function with an exception to return the original tree.

Here is what a deletion would look like for something that is not in the tree. As you recurse you create a new Node with the key deleted in the correct subtree. In this particular case the delete function will recurse to a Leaf then return a Leaf and on each step back up the stack return a newly constructed Node. This new path is represented as the blue path below. Since there is no structure to unwind the new path to the old path we re-create the search path in the result tree.

let at = delete x bt

non-existent deletion

To fix this issue, as mentioned wrap the function in an exception.

let delete k t =
    let rec delete k = function
        | Leaf -> raise Not_found
        ...
    in
    try delete k t with Not_found -> t

Upvotes: 2

Related Questions