1

我正在binary search treeOCaml 中构建操作。

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代码是否足够好或有任何改进?

4

1 回答 1

2

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

这是对不在树中的内容进行删除的样子。当您递归时,您创建一个新Node的,并在正确的子树中删除了键。在这种特殊情况下,delete 函数将递归到 aLeaf然后返回 aLeaf并且在堆栈的每一步备份中返回一个新构造的Node。这条新路径表示为下面的蓝色路径。由于没有将新路径展开到旧路径的结构,我们在结果树中重新创建搜索路径。

let at = delete x bt

不存在的删除

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

let delete k t =
    let rec delete k = function
        | Leaf -> raise Not_found
        ...
    in
    try delete k t with Not_found -> t
于 2013-03-11T17:22:00.370 回答