- 1、本文档共3页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
探索C#之跳跃列表
一、 基本介绍
SkipList是William Pugh在1990年提出的,它是一种可替代平衡树的数 据结构。SkipList在实现上相对比较简单,比如在限定时间条件下,能非常轻 松的实现SkipList,但却实现不了 B树、红黑树、AVL树等,想一想单B树 的 删除,就要考虑非常多的细节。虽说SkipList简单,但性能却非常高,在平均 情况下,其插入、删除、查找数据时间复杂度都是0(log(N)),其最坏情况下 都为0(N),这点要低于平衡树。
由于skipList的高效及维护简单,所以很多大数据系统中在维护有序列表 是都会使用SkipList,比如LevelDB在内存中暂存数据的结构MemTable就是使 用SkipList实现的,Redis在Sorted Set数据结构时也采用的是SkipList,还 有Lucene中同样采用SkipList来对倒排列表进行快速查找。
SkipList依赖随机生成数以一定概率来保持数据在树上的平衡分布,所以 SkipList也属于概率算性的数据结构,和之前介绍的BoolFilter属于一个类型 C#之布隆过滤器(Bloom filter)。
二、 算法思想
举个例子,楼主逛完街要回张江玉兰香苑,如果从人民广场做公交车回去, 要路过非常多的站:
18(人民广场)
21
23(东昌路)
27
30
33
35
36
40(广兰路)
45
47
想想这么远的路程,多悲惨(在大数据情况下找对应项同样的问题),相较来 说坐地铁就快很多,然后到广兰路换程。这就是SkipList最核心的思想非常简 单。现在路线变成:
18
_ 23
33
?V/ V 1 V ▼- v ? ?
40
47
18(人民广场)
21
23(东昌路)
27
30
33
35
36
40(广兰路)
45
47
因为可以一次跨越很多不需要的站,所以就快了很多。如果可以搭朋友顺风 车的话,变成:
18
40(扔你到这)
47
18
23
33
40
47
18(人民广场)
21
23(东昌路)
27
30
33
35
36
40(广兰路)
45
47
这个图就非常接近SkipList的结构及思想了。
三、演化步骤
大致了解怎么回事了、看具体怎么实现。首先我们忘记树、图等高级概念 及结构,回到我们刚学到链表的时候。再看上面的回家路线图,我们把最下面 一层当成一个链表,每个节点(站)指针指向下一个节点(站)。单个有序链表:
按照传统的操作有序链表的做法,如果需要查找其中一条数据,需要顺序遍 历。按照地铁的思路,如果给一部分的节点增加个指向后面的节点指针,假设 一半节点增加,最多遍历[n/2]+l次即可找到任意节点。这里把18、23、33、40、 47节点都多增加个指针指向后面的节点:
以此类推,继续增加3、4个等更多的指针,使其指向更远的后方节点,这 样可以更好的提高查询效率。3个节点的情况:
如果理想情况下查找,就类似二分查找了。SkipList通过随机数(丢硬币 决定)在插入节点时,随机判定该节点应该有多少个执行后续节点的指针。有几 个执行后面节点指针,就是在第几层,比如上图18存在3个指针指向后面,它 就在第三层,23有2个指针就在第二层。
四、实现细节
1、搜索
在同一层查找节点时和普通有序链表一样,顺序向后查找,查到返回,否则 进入下一层继续向后查找。比如查找35,会从最顶层搜索比较18、相等返回, 大于比较40继续下一层找,比较1、23、33、40后继续下一层,比较33、35 正确返回、否则不存在。
2、更新
搜索到值后更新:
SkipListNodeTKey, TValue position; bool found 二 search(key, out position); if(found)
position. value= value;
3、 插入
插入时,如果值存在则更新,不存在插入。如上图,假如要插入29,需要 先查找到27插入到后面,如果扔硬币后得到3,那么依次增加指向后面节点的 指针。
4、 随机数
也称丢硬币做法。
Random generator = newRandom();
int levels = 0;
while (generator. NextDouble() 0.5levels=maxlevel)
levels++;
return levels;
删除同插入一样,如果找到,调整相对应的指针顺序,然后删除节点。
文档评论(0)