简体   繁体   English

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

[英]Deletion in Binary Search Tree in OCaml

i am constructing the operations of binary search tree in 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)

Can anyone tell me whether my deletion code is good enough or any improvement? 谁能告诉我我的deletion代码是否足够好或有任何改进?

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. 递归时,将创建一个新Node ,并在正确的子树中删除密钥。 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 . 在这种特殊情况下,delete函数将递归到Leaf然后返回Leaf并在备份的每一步中返回新构造的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

不存在的删除

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

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

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