redis zset 为什么选用跳表?
最近了解了下redis的zset,发现是用跳表实现的,这就引入出来一个话题:为什么redis使用跳表来实现zset,而不是其他的数据结构,比如B+树等
跳表
在链表的基础上,逐层添加索引,提高查询与插入效率O(logn),如下图所示:
查找
从最稀疏的顶层搜索,直至需要查找的元素落在该层两个相邻的元素中间。接着,算法将进入下一层,重复刚刚的搜索过程,直到找到需要查找的元素。
插入&删除
在查找的基础上,先找到待插入的位置,在最底层插入该元素,接着按照投硬币的方式,往上建立索引层
- 投硬币:50%的概率在上层建立索引层,通过概率事件,避免某一段区间内节点过多,导致性能退化成数组O(n)
- 建立索引的时候,需要使用节点的节点的前驱与后驱,所以在实际查找过程中,需要额外保存查询路径中,经过每层的最小&最大节点,从而完成所以节点的构建
删除过程与上述类似,这里不在赘述
zset
zset实际上是跳表+kv的map,支持key和range的查询
redis不用B+树,而用跳表,我理解主要是由于:
- 跳表实现简单,就是这么单纯的道理
- 跳表无需笨重的调整,B+树有调整的代价
- 跳表占用空间比B+数要小
参考
聊聊跳表原理及为什么Redis要使用跳表来实现zset - 云+社区 - 腾讯云