创建双向链表的实例

时间:2017-12-28 10:37:12

标签: list ocaml circular-reference

我已经获得了以下双重链表的实现:

type 'a elem = {v : 'a; mutable next : 'a lista; mutable prev : 'a lista}
and 'a lista = 'a elem option;;

使用此实现我试图制作一些示例列表。一个元素列表很容易制作:

let bla_1 = Some {v = 1; next = None; prev = None};;

我猜一个空列表将是两个无节点。但我不知道如何制作包含更多元素的列表。

1 个答案:

答案 0 :(得分:4)

如果要构建包含两个元素xy的列表,则必须确保有两个类型为'a elem的值彼此指向(不包括中间选项)输入'a lista)。最终,您需要一个圆形结构:

  • lx绑定到{ v = x; next = Some ly; prev = None }
  • ly绑定到{ v = y; next = None; prev = Some lx}

可以在OCaml中具有相互递归的值(感谢octhacron):

let rec x = { v = 0; next = Some y; prev = None} 
    and y = { v = 1; next = None; prev = Some x}

但这很难用于构建更复杂的列表。这就是您拥有可变字段的原因:您可以构建节点,然后通过更改其nextprev字段来连接它们。例如,您首先定义lxnext字段设置为None,并且只有在知道ly之后,才能替换{{1}指向的值} lx.next

下面是一个将常规列表转换为双向链表的函数;在递归调用时,它构建节点;从递归调用返回时,它会修改Some ly节点,使其通过next字段指向当前节点:

prev

所以:

let rec to_dbl_list = function
    [] -> None
  | x::xs ->
     let node = { v = x; prev = None ; next = (to_dbl_list xs)} in
     let current = Some node in
     (match node.next with
        None -> ()
      | Some next -> (next.prev <- current)) ;
     current ;;