linked-list - Ocaml双链表: remove a node satisfying a condition from a double linked list

标签 linked-list pattern-matching match ocaml doubly-linked-list

我们有一个双向链表,定义为:

type 'a llist =
  | Nil
  | Cons of (float *'a) * 'a lcell * 'a lcell
and 'a lcell = ('a llist) ref

我已经实现了一个添加头功能,如下所示:

let add_head x head = 
  match !(!head) with
  | Nil -> head := !(singleton x)
  | Cons (e, previous, next) -> 
      let temp = Cons (x, ref Nil, !head) in
      previous := temp;
      head := previous;; 

请注意,为了实现添加头,我使用了单例函数

let singleton (init: float * 'a): 'a lcell ref =
  let l = ref (Cons (init, ref Nil, ref Nil)) in
  let front = ref l in
  front

我的问题是,当我尝试删除一个元素时,我试图编写一个删除函数remove: (float -> bool) -> 'a lcell ref -> unit,这样 remove p head 删除时间戳满足谓词 p: float -> bool 的第一个节点。如果没有节点的时间戳满足谓词,则列表应保持不变。

这是我到目前为止所拥有的:

let remove p head =
  let rec remove' ll =
    match !ll with 
    | Nil -> head := !head
    | Cons ( (d,_), previous, next) ->
        if p d then
          match (!previous, !next) with 
          | (Nil, Nil) -> head := ref Nil   (* empty list*)
          | (Nil, Cons ( d1, p1, n1)) -> (* this is the head, remove it and reassign head*)
              head := next; 
              p1 := Nil
          | (Cons ( d2, p2, n2), Cons ( d1, p1, n1)) -> (* this is middle, remove it and fix pointers of previous and next*)
              n2 := !next;
              p1 := !previous 
          | (Cons ( d1, p1, n1), Nil) -> (* this is tail, remove it and make previous one the tail*)
              n1:= Nil 
        else remove' next              
  in
  remove' !head

我在删除列表中间的项目时遇到问题,即不是头部或尾部。我也无法删除多个元素。有人可以尝试帮助我吗,我想我的比赛案例中遗漏了一些东西。

最佳答案

当你在比赛声明中使用 cons cons 时,你就搞砸了 您必须替换 previous 和 next 而不是 n2 和 p1 应该是

| Cons(d2, p2, n2), Cons (d1, p1, n1) ->
`previous := Cons(d2, p2, next);`
`next := Cons(d1, previous, n1);

关于linked-list - Ocaml双链表: remove a node satisfying a condition from a double linked list,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58438562/

相关文章:

java - k 反转链表

c - C中的链表结构与读取txt

c - 排除编译时循环链表错误

c# - 正则表达式根据匹配替换为单独的替换

regex - 语言独立 : Check if a string consists of a multiple of a certain substring

haskell - Haskell 中的模式匹配数据类型。捷径?

mysql - 与 MYSQL 匹配返回 SSAT,但不返回 SAT

c - 从链表中删除选择的节点

enums - Rust:在没有其他模式匹配的情况下获得枚举值的所有权

excel - 索引和匹配矩阵公式