【问题标题】:Why are append and uncons for catenable lists merely amortized O(1)?为什么可连接列表的 append 和 uncons 仅摊销 O(1)?
【发布时间】:2015-02-01 19:04:59
【问题描述】:

我采用了 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) 操作(最坏情况或摊销)的队列实现,appenduncons 被摊销 O(1)

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

【问题讨论】:

    标签: data-structures sml ml purely-functional


    【解决方案1】:

    关于您对可连接列表的问题。您还需要考虑到强制暂停可能会导致一连串的力量。请注意,linkAll 强制其输入列表,这可能是尚未评估的暂停“s”。强制“s”可能反过来强制另一个暂停等等。 如果您对列表执行一系列 uncons 操作,这确实会发生。最终,最多在 'n' 个 uncons 操作之后,数据结构可能退化为朴素的 Cons 列表 (Cons(x, Cons(y, ...))),其中 'n' 是列表的大小。任何进一步的 uncons 操作都将具有恒定的时间。 因此,数据结构确实有一个摊销的常数时间界限,但这不是最坏的情况。

    【讨论】:

      【解决方案2】:

      不可变(纯函数式)队列只有 O(1) 分期的构造函数和析构函数。

      http://www.westpoint.edu/eecs/SiteAssets/SitePages/Faculty%20Publication%20Documents/Okasaki/jfp95queue.pdf

      【讨论】:

      • 您发布的链接的摘要说:“我们提出了队列和双端队列(deques)的纯功能实现,每个操作只需要 O(1) 时间在最坏的情况下。” [强调我的]
      • 而且,如果您认为惰性是一种影响(因为惰性 thunk 内部会发生变异),Hood-Melville 队列是队列的另一个示例,其操作都是最坏情况 O(1),它们不会甚至需要内部突变。
      猜你喜欢
      • 2018-02-13
      • 2018-02-08
      • 2011-12-16
      • 1970-01-01
      • 2010-10-12
      • 2022-01-15
      • 2011-01-27
      • 2013-02-28
      • 2017-12-26
      相关资源
      最近更新 更多