简体   繁体   中英

Creating instances of a doubly linked list

I have been given the following implementation of a doubly linked list:

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

Using this implementation I'm trying to make some example lists. A one element list is easy to make:

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

And I guess an empty list would be two None nodes. But I don't know how to make lists with more elements.

If you want to build a list with two elements x and y , you have to ensure you have two values of type 'a elem pointing to each other (not counting the intermediate option type 'a lista ). Eventually, you need to have a circular structure where:

  • lx is bound to { v = x; next = Some ly; prev = None } { v = x; next = Some ly; prev = None } { v = x; next = Some ly; prev = None } ,
  • and ly is bound to { v = y; next = None; prev = Some lx} { v = y; next = None; prev = Some lx}

You can have mutually recursive values in OCaml (thanks octhacron):

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

But this gets hard to use to build more complex lists. And that's why you have mutable fields: you can build nodes and then connect them by changing their next and prev fields. For example, you first define lx with the next field set to None , and only after you know what is ly , you can replace the value pointed by lx.next by Some ly .

Here below is a function that converts a regular list into a doubly-linked list; when calling itself recursively, it builds nodes; when returning from a recursive call, it modifies the next node so that it points back through its prev field to the current one:

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 ;;

And so:

# to_dbl_list [1; 2; 3];;
- : int lista =
Some
 {v = 1;
  next =
   Some
    {v = 2; next = Some {v = 3; next = None; prev = <cycle>}; prev = <cycle>};
  prev = None}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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