【问题标题】:Skip lists, why we need more than one insertion?跳过列表,为什么我们需要不止一个插入?
【发布时间】:2021-05-16 00:43:28
【问题描述】:

我正在学习skip lists,但有些东西我无法理解。

当我们插入一个新节点时,我们扔一个硬币,如果我们得到 1,我们会在上层再次插入节点,依此类推,直到我们得到 0,我们停止。

但是为什么我们需要这个呢?

【问题讨论】:

  • 这个问题听起来很像“为什么跳过列表的结构类似于跳过列表?”这是一个重言式。您是在问“跳过列表的意义何在?”您可以在连续数组上进行二进制搜索,但不能在链表上进行。这就是链表需要做的事情才能获得这种能力。插入时的随机“硬币翻转”似乎是一种选择分裂大约一半时间的方法,而不会像平衡红黑树这样的成本复杂性。
  • 跳过列表的实现细节on wiki很好地解释了抛硬币促销的原因。简而言之,翻转的随机性将数据结构构建为伪平衡。
  • 如果不进行额外的插入,跳过列表中就不会跳过。

标签: c++ list algorithm skip-lists


【解决方案1】:

如果只将一层添加到跳过列表中,则会得到一个有序链表,其中每个节点都连接到下一个节点。

跳过列表中的额外层用于有效搜索其中的值,将查找时间从O(n)减少到O(logn)

  • 仅使用“常规”有序链接列表(无额外层),您平均需要 ~n/2 次迭代来查找值是否存在。
  • 如果添加单层,则需要一半,这意味着 ~n/4 次迭代。
  • 如果添加两层,您将需要之前的一半,或平均约 n/8 次迭代。

(以上是简化,因为您还需要遍历下一层,但它们的复杂性与顶层相似)

通过一直持续到顶部,您将需要平均O(1) 迭代每层,从而为您提供O(logn) 总查找时间。

【讨论】:

    猜你喜欢
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-09
    • 2013-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-23
    相关资源
    最近更新 更多