在OCaml中的二进制搜索树中删除

时间:2013-03-11 16:50:24

标签: functional-programming ocaml

我正在OCaml中构建binary search tree的操作。

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)

有谁可以告诉我,我的deletion代码是否足够好还是有任何改进?

1 个答案:

答案 0 :(得分:2)

当我们插入树中的内容或删除不在树中的内容时,会出现一种改进。这些操作中的每一个都将复制到该特定节点的搜索路径。插入可能不是问题,因为您需要更新该键的值,但删除可能是您可以进行改进的情况。这可以通过使用异常包装函数来返回原始树来解决。

以下是对于不在树中的内容的删除。当你递归时,你创建一个新的Node,并在正确的子树中删除了密钥。在这种特殊情况下,delete函数将递归到Leaf,然后返回Leaf,并在每个步骤上返回堆栈返回一个新构造的Node。此新路径表示为下面的蓝色路径。由于没有结构可以解开旧路径的新路径,我们在结果树中重新创建搜索路径。

let at = delete x bt

non-existent deletion

要解决此问题,如上所述将函数包装在异常中。

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