跳表概念
增加了向前指针的链表叫作跳表。跳表全称叫做跳跃表,简称跳表。跳表是一个随机化的数据结构,实质就是一种可以进行二分查找的有序链表。跳表在原有的有序链表上面增加了多级索引,通过索引来实现快速查找。跳表不仅能提高搜索性能,同时也可以提高插入和删除操作的性能。
使用场景
- redis ZSET(有序集合 sorted set)
- kafka 的每个日志对象中使用了 ConcurrentSkipListMap 来保存各个日志分段,每个日志分段的 baseOffset 作为 key,这样可以根据指定偏移量来快速定位到消息所在的日志分段。
- lsm-tree
跳表的高度
假设有n个元素,那么第一层索引的个数为 n/2,第二层的个数为 n/4,那么第k层的个数为 n/2^k,当k层的个数为2的时候则不在增加。算出层高 h = log2(n)-1, 所以最后得出跳表的时间复杂度是O(logn),其每种操作(
搜索、插入、删除)的平均复杂性均为O(logn)
更新索引
插入元素更新哪一节索引?
答:因为上层节点的个数是下层节点个数的1/2所以我们希望更新上层节点的概率为1/2。 所以采用抛硬币的算法,
k默认为1,当正面时k++,继续抛硬币重复之前操作,但也不能让他无限增长,不能超过预定的最高层max_level,最终更新第一层到第k层的索引。
实现代码
https://github.com/wo4zhuzi/algorithm_notes/blob/main/skiplist/skiplist.go