面试题答案
一键面试-
确定新节点的层数:
- Redis跳跃表节点的层数是随机生成的。在Redis的实现中,使用一个随机函数来决定新节点的层数。具体来说,随机函数以一定概率(通常是1/2)决定是否让新节点的层数增加1。
- 生成随机层数的代码示例(简化的伪代码):
int randomLevel() { int level = 1; while ((random() & 0xFFFF) < (0.5 * 0xFFFF)) { level++; } return (level < ZSKIPLIST_MAXLEVEL)? level : ZSKIPLIST_MAXLEVEL; }
- 这里
ZSKIPLIST_MAXLEVEL
是跳跃表允许的最大层数(在Redis中通常定义为32)。
-
插入新节点并修改指针:
- 首先从跳跃表的表头开始,沿着当前层的指针查找插入位置。在每一层,从表头的当前层指针开始,比较节点的键值,找到第一个键值大于要插入节点键值的节点
x
,记录下当前层的x
节点到一个数组update
中,然后下降到下一层继续查找。 - 查找结束后,
update
数组中记录了每一层插入位置的前驱节点。 - 创建新节点,设置新节点的键值、层数等信息。
- 从最底层开始,修改指针将新节点插入到跳跃表中。对于每一层
i
,将update[i]
的forward[i]
指针指向新节点,同时将新节点的forward[i]
指针指向update[i]->forward[i]
原来指向的节点。 - 例如,假设要插入的新节点为
newNode
,当前层的前驱节点为update[i]
:
newNode->forward[i] = update[i]->forward[i]; update[i]->forward[i] = newNode;
- 这样就完成了新节点在该层的插入,重复这个过程直到最高层,从而维持跳跃表的结构。
- 首先从跳跃表的表头开始,沿着当前层的指针查找插入位置。在每一层,从表头的当前层指针开始,比较节点的键值,找到第一个键值大于要插入节点键值的节点
通过以上步骤,就可以在Redis跳跃表中成功插入一个新节点。