data-structures – 为什么appened和uncons for catenable list只是摊销O(1)?

我拿了Okasaki的catenable列表的实现,并重构了一点,以避免布尔盲目性问题.除此之外,数据结构本身保持不变:

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)操作队列的实现(最坏情况或摊销),追加和解除摊销是摊销O(1).

为什么他的主张不能得到加强?给定实时队列的实现(所有操作都是最坏情况的O(1)),append和uncons看起来最坏情况O(1)给我. linkAll中的所有递归调用都由L.delay保护,并且没有任何公共操作强制执行多次暂停.我的推理(或我的代码)错了吗?

最佳答案 关于您对可悬挂列表的问题.您还需要考虑强制暂停可能会导致一连串的力量.请注意,linkAll强制其输入列表,这可能是尚未评估的暂停”.强迫’s’可能反过来强制另一个暂停,等等.

如果您在列表上执行一系列uncons操作,确实会发生这种情况.最后,最多在’n’uncons操作之后,数据结构可能退化为天真的Cons列表(Cons(x,Cons(y,…))),其中’n’是列表的大小.任何进一步的uncons操作都将有恒定的时间.

因此,数据结构确实具有摊销的常量时间限制,但这不是最坏的情况.

点赞