跳表的实现
跳表概念#
增加了向前指针的链表叫作跳表。跳表全称叫做跳跃表,简称跳表。跳表是一个随机化的数据结构,实质就是一种可以进行二分查找的有序链表。跳表在原有的有序链表上面增加了多级索引,通过索引来实现快速查找。跳表不仅能提高搜索性能,同时也可以提高插入和删除操作的性能。
使用场景#
- 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通