【发布时间】:2019-02-09 18:41:16
【问题描述】:
我已经阅读了this question,但这不是我想要的。
据我所知,删除包含n 元素的跳过列表中的第一个m 元素需要O(m),或者如果m 不重要,我们可以说O(1)。但是为什么 Redis 中的 ZPOPMIN 需要 O(log n)?
【问题讨论】:
标签: data-structures redis time-complexity skip-lists
我已经阅读了this question,但这不是我想要的。
据我所知,删除包含n 元素的跳过列表中的第一个m 元素需要O(m),或者如果m 不重要,我们可以说O(1)。但是为什么 Redis 中的 ZPOPMIN 需要 O(log n)?
【问题讨论】:
标签: data-structures redis time-complexity skip-lists
我不知道 Redis 的具体实现。但是,如果使用 Skip List 实现排序集,则删除将采用O(log n)。
通过对跳过列表的构建方式的观察,我想您可能会明白。这不是使用简单的单个数组来实现的,这将花费O(m) 时间来删除第一个m 元素。相反,它使用多个数组(将其视为链表)并巧妙地存储值以支持O(log n) 时间的添加/删除/搜索。
如果它是使用单个数组实现的,那么你是对的 - 删除应该花费O(m) 时间。但是,跳过列表并非如此。我正在尝试添加一张图片,您可以从中了解列表的构建方式。
希望对您有所帮助!
更新
请记住,跳过列表有级别。跳过列表可以拥有的最大级别数是O(log n)。让我们考虑删除这里的前三个元素(即 12、17、20)。要首先删除 12,我们必须修改级别 2 和级别 1,因为我们必须在两个级别中将 - ∞ 指向 17。删除 12 后,我们删除 17 并在此处也执行相同操作。对于每次删除,我们可能必须迭代最多O(log n) 级别,如上所述关于最大级别数。我希望你能明白。
【讨论】:
25,我们可以将 25 左指针更新为与头部双指向。然后向左一一移动,得到第 5 层的值。找到17,更新指针,使头部与尾部双指向。然后,只需删除第 5 层的指针,因为它只是头尾之间的指针。
25s 指向头部,那么在最坏的情况下您需要多少个25s 指向头部?
25s?然后我们就不需要关心1-4级的12、17和20了