OCaml中的双端队列-what';什么主意?
我遇到了一个deque的实现:OCaml中的双端队列-what';什么主意?,ocaml,deque,imperative-programming,Ocaml,Deque,Imperative Programming,我遇到了一个deque的实现: type 'a elem = { mutable l1 : 'a elem; mutable l2 : 'a elem; v : 'a option } type 'a queue = { mutable front : 'a elem; mutable back : 'a elem } let init () = let rec g1 = { l1 = g1; l2 = g2; v = None} and g2 = { l1 = g2;
type 'a elem = { mutable l1 : 'a elem; mutable l2 : 'a elem; v : 'a option }
type 'a queue = { mutable front : 'a elem; mutable back : 'a elem }
let init () =
let rec g1 = { l1 = g1; l2 = g2; v = None}
and g2 = { l1 = g2; l2 = g1; v = None}
in
{ front = g1; back = g2 }
let is_empty q =
let f = q.front
and b = q.back
in
f.l2 == b
let put_between p q x =
let r = { l1 = p; l2 = q; v = Some x }
in begin
if p.l1 == q then p.l1 <- r else p.l2 <- r;
if q.l1 == p then q.l1 <- r else q.l2 <- r
end
type'a elem={mutable l1:'a elem;mutable l2:'a elem;v:'a option}
键入'a queue={mutable front:'a elem;mutable back:'a elem}
设init()=
设rec g1={l1=g1;l2=g2;v=None}
g2={l1=g2;l2=g1;v=None}
在里面
{前面=g1;后面=g2}
让它是空的=
设f=q
b=q.back
在里面
f、 l2==b
让我们把_放在pqx之间=
设r={l1=p;l2=q;v=somex}
开始
如果p.l1==q,那么p.l1稍微扩展一下@Lee所说的内容,这是一个双端队列(或deque)的简单易变实现,就像用普通指针(如C)编写的语言一样
除了保持链接笔直外,我只能看到一些具体的想法
deque的每一端都有一个标题(@Lee称之为哨兵)。所以一个空的deque中有两个节点。由于双向链接,每个节点指向另一个节点。(这可能就是您所指的递归。)
因为OCaml是强类型的,所以所有节点都必须是相同的类型,甚至是末尾的头。由于标题中没有值,因此需要对值使用'a选项
。换句话说,您需要允许节点中没有值
put\u-between
的调用者需要提供两个相邻的节点,但它们可以按任意顺序提供
代码使用“物理相等”(==
)来测试节点的标识。在OCaml中这样做是危险的,但在这里是正确的。可以将可变值与==
进行比较,或多或少会得到命令式语言中比较指针的结果
学习OCaml的一个原因是学习函数式编程。这段代码对此没有用处,因为(正如我所说)它是一个可变的实现。您可以在的第5章中看到一些实际的功能性deque实现。(你也可以买他的书,这是他长期以来的最爱。)它看起来像一个有两个前哨节点的双链接列表。虽然这两种记录类型不是相互递归的-elem
是递归的,但没有引用队列
。但是为什么我们要使用四个链接:front.l1
,front.l2
,back.l1
,back.l2
。在纯C(++)中,您只需使用两个指针-指向下一个和上一个元素每个节点都有两个其他节点:l1
和l2
。有两个链接,而不是四个。队列对象('A queue
)包含两个头,因此队列对象内总共有四个链接。Aaaa、sofront
和back
是虚拟对象,l1
是前一个节点,l2
是下一个节点?是的,这是正确的。我不会称它们为“虚拟”对象,但它们是空节点。使用头稍微简化了代码,特别是在OCaml中,它具有强大的类型。(一个空的deque必须与其中包含一些节点的deque类型相同。)好吧,但是这里有一些奇怪的东西。前一个back
元素是back
本身,下一个元素是front
。背后有什么逻辑吗?