当前位置: 首页 > 知识库问答 >
问题:

为什么redis zrank的复杂性是O(log(N))

米俊喆
2023-03-14

Redis zrank。

返回存储在key处的排序集中成员的排名,分数从低到高排序。排名(或指数)是基于0的,这意味着得分最低的成员排名为0。

为什么复杂度是O(log(N))?成员按分数排序,但zank按成员查询。

我找到了一些可能是答案的东西。

A.zset由ziplist实现时

  1. 大小小于128
  2. 每个成员的大小小于64字节

所以,ziplist的大小很小,所以这不是我讨论的问题。

B.当zset由skiplist实现时,zset的实现是:

typedef struct zset {

    zskiplist *zsl;

    dict *dict;

} zset;

zset同时保存一个dict和一个skiplist。

  1. dict保持成员到分数的映射
  2. zsl是按分数排序的对象列表。对象包含成员和分数

所以,zrank是这样的:

>

  • 用O(1)时间求成员的分数。如果找不到,返回nil

    使用找到的分数在zsl中搜索,花费O(log(N))时间。

  • 共有2个答案

    史劲
    2023-03-14

    Redis对排序集使用两种编码之一:ziplists和skip list。

    较小的集合是ziplists,它们的排序复杂度实际上是O(N)。然而,这被认为是O(1),因为ziplist阈值是恒定的。

    当使用跳过列表编码时,排名是O(LogN),因为搜索的便利性——参考维基百科关于跳过列表的文章了解更多信息。

    訾淇
    2023-03-14

    成员键很可能存储在某种搜索树中(通过这样的分支大小进行扩展)。

    因此,元素搜索和秩计算都是在O(logN)中进行的。上面的链接显示了这些操作的示例实现。

     类似资料:
    • 问题内容: 来自redis doc: ZPOPMIN键[count]自5.0.0起可用。 时间复杂度:O(log(N)* M),其中N为排序集中元素的数量,M为弹出元素的数量。 删除并返回存储在key排序集中的得分最低的成员。 因此,我的问题是,如果列表已排序,为什么要使用log n,为什么不使用O(1)? 问题答案: 如果 列表 已排序,为什么要使用log n,为什么不使用O(1)? 如果使用列

    • 查找p的伪码算法为: 假设我有一个int值的数组H[1到m],其中“p”是峰值元素,如果: 基本上,如果H【p】大于或等于其相邻元素,则H【p】为峰值。 假设数组H在开始和结束时都大于1个元素,数组为H[0到m 1],其中H[0]=H[m 1]=无穷大。因此,H[0]和H[m 1]是哨兵。然后是元素p,其中1≤ p≤ n、 是一个峰值,如果H【p-1】≤ H【p】≥ H【p 1】。 我认为渐近时间

    • 问题内容: 我刚刚开始学习数据结构,并且在进行数组插入时想知道为什么数组插入的时间复杂度为O(n)而不是O(n + 1)? 在最佳情况下,当插入在最后时,时间复杂度为O(1)。我想我们正在考虑1插入元素,因为这里没有元素被移动。在最坏的情况下,假设我们必须移动n个元素然后插入新元素,那么时间时间复杂度是否应该为O(n + 1)?n用于移动元素,1用于插入。 非常感谢您的帮助。 问题答案: O(n)

    • 即使在最坏的情况下,是否有任何数据结构可以提供O(1)——即常数——插入复杂性和O(log(n))搜索复杂性? 排序后的向量可以进行O(log(n))搜索,但插入需要O(n)(考虑到我并不总是在前面或后面插入元素这一事实)。而列表可以进行O(1)插入,但不能提供O(log(n))查找。 我想知道这样的数据结构是否可以实现。

    • 我不明白堆排序的空间复杂度是怎样的O(1)?虽然快速排序不使用任何额外的数组(即就地),但在最坏情况下其空间复杂度为O(n),在最佳情况下为O(lg n),因为在递归调用的后端使用堆栈。我说得对吗? 堆排序也是如此。虽然,它是就地的,但是由于Build-Heap函数调用Max-Heapify函数,所以它的空间复杂度应该等于Max-Heapify,即O(lg n)。不是吗?此外,稍后在根节点调用Ma