【问题标题】:Implementation of a circular doubly linked list in OCamlOCaml中循环双向链表的实现
【发布时间】:2020-09-08 19:48:35
【问题描述】:

我正在尝试使用 OCaml 类型声明来实现循环双向链表。这是我所拥有的:

type 'a cList = 
{ 
mutable value : 'a; 
mutable left : 'a cList option; 
mutable right : 'a cList option 
}
;;

当我需要声明包含单个元素的第一个列表时,问题就出现了。因为在分配之前无法引用元素,所以我无法让单元格的左右成员指向自身。 到目前为止,我唯一的解决方法是允许左右成员为 type 选项,将它们设置为 None,然后修改它们,使它们指向单元格本身。

let unitClist v = let a = {
                      value = v; 
                      left = None; 
                      right = None
                      }
              in
              a.left <- Some a; 
              a.right <- Some a;
              a
;;

它可以工作,但是当您确定有一个值时,必须使用选项类型有点绑定。 有更好的方法吗? 提前致谢。

【问题讨论】:

  • 我认为这正是应该通过将let 替换为let rec 而消失的问题?

标签: data-structures ocaml doubly-linked-list circular-list


【解决方案1】:

显然你也可以直接用记录定义一个递归值。通过使用rec 绑定,您可以在定义中递归地引用绑定(在某些情况下):

type 'a cList = {
  mutable value : 'a; 
  mutable left : 'a cList; 
  mutable right : 'a cList 
}

let unitClist v =
  let rec a = {
    value = v; 
    left = a; 
    right = a
  }
  in a

这在Chapter 8.1 of the OCaml Manual中有记录

【讨论】:

    【解决方案2】:

    您可以改用对象,它们是后期绑定,因此允许自引用:

    object(self)
      method value = v
      method left = self
      method right = self
    end
    

    这当然会带来性能成本,因为所有方法调用都将被动态分派,但否则这是不可能的,因此这是必要的权衡。如果不使用某种间接方式,您将无法引用尚不存在的内容(编辑:堆分配的记录已经存在。请参阅my other answer)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-13
      • 2021-07-05
      • 1970-01-01
      • 2013-11-15
      • 2021-11-18
      • 2011-06-03
      • 2018-03-14
      相关资源
      最近更新 更多