我采用了 Okasaki 的可连接列表实现,并对其进行了一些重构以避免布尔盲问题。除此之外,数据结构本身保持不变:
functor CatList (Q : QUEUE) :> CAT_LIST =
struct
(* private stuff, not exposed by CAT_LIST *)
structure L = Lazy
structure O = Option (* from basis library *)
datatype 'a cons = ::: of 'a * 'a cons L.lazy Q.queue
infixr 5 :::
(* Q.snoc : 'a Q.queue * 'a -> 'a Q.queue *)
fun link (x ::: xs, ys) = x ::: Q.snoc (xs, ys)
(* L.delay : ('a -> 'b) -> ('a -> 'b L.lazy)
* L.force : 'a L.lazy -> 'a
* Q.uncons : 'a Q.queue -> ('a * 'a Q.queue lazy) option *)
fun linkAll (xs, ys) =
let
val xs = L.force xs
val ys = L.force ys
in
case Q.uncons ys of
NONE => xs
| SOME ys => link (xs, L.delay linkAll ys)
end
(* public stuff, exposed by CAT_LIST *)
type 'a list = 'a cons option
val empty = NONE
(* L.pure : 'a -> 'a L.lazy *)
fun append (xs, NONE) = xs
| append (NONE, xs) = xs
| append (SOME xs, SOME ys) = SOME (link (xs, L.pure ys))
(* Q.empty : 'a Q.queue *)
fun cons (x, xs) = append (SOME (x ::: Q.empty), xs)
fun snoc (xs, x) = append (xs, SOME (x ::: Q.empty))
(* O.map : ('a -> 'b) -> ('a option -> 'b option) *)
fun uncons NONE = NONE
| uncons (SOME (x ::: xs)) = SOME (x, L.delay (O.map linkAll) (Q.uncons xs))
end
在他的书中,Okasaki 声称,给定具有O(1)
操作的队列的实现(最坏情况或摊销),append
并且uncons
是摊销的O(1)
。
为什么他的主张不能得到加强?给定实时队列的实现(所有操作都是最坏情况O(1)
),append
在我uncons
看来是最坏情况O(1)
。所有递归调用linkAll
都由 保护L.delay
,并且没有任何公共操作会强制暂停一次以上。我的推理(或我的代码)错了吗?