跳跃链表详解
链表存在一个严重的缺陷:他们需要顺序扫描,才能找到所要查找的元素,查找是从链表的开头开始的,只有找到了所查找的元素,或者直到链表的末尾都没有找到这个元素才会停下来。将链表中的元素排序可以加速查找的过程,但仍然需要顺序查找,因此链表最好是允许跳过某些节点,以避免顺序处理。
大纲(Outline)
1.Building a skip list. (创建)
2.Search. (查找)
3.Insertion (插入)
Building a skip list. (创建)
Initially,a linked list contains n numbers in ascending order.
虽然该链表是升序的,但是无法做二分查找,因为不知道中间节点的地址;既然困难之处在于寻找中间节点,那么,自然想到的就是加一些指针帮助跳跃,用来访问中间节点。
先加一个哨兵节点,作为第0层,L0是一个指针。L0层的节点是原始链表,没有跳跃。
建立L1层链表,随机找几个节点增加一层;
如图可知,L1层链表相对于L0层链表,更加稀疏,如果此时访问节点20时,肯定L1层链表更快;
依次类推,建立L2,L3层链表
这样我们已经搭建好了跳跃链表,这里共有4层,层数取决于用户自己定义。
2.Search. (查找)
example 1:search key = 13
查找从最上层链表开始找起,从Sentinel出发,沿着L3向右走一步,到达节点13,比较一下key,发现相等,找到了,返回当前节点地址。
example 2:search key = 8
key = 8 < 13,说明地址介于Sentinel和节点13之间,所以要在Sentinel和节点13之间查找。
向下走一层,到达L2层,沿着L2层向右走一步,到达节点2,key = 8 > 2 ;
所以从节点2出发向右走一步,到达节点13,key = 8 < 13,说明地址介于节点2和节点13之间,所以要在节点2和节点13之间查找。
我们向下走一层,到达L1层,从节点2出发,沿着L1层向右走一步,到达节点10 ;key = 8 < 10;说明地址介于节点2和节点10之间,所以要在节点2和节点10之间查找。
我们向下走一层,到达L0层,从节点2出发,沿着L0向右走一步,到达节点8;找到了,返回节点8的地址;
example 3:search key = 20
L3: Sentinel ——> 节点13
↓
L2:节点13——>节点26
↓
L1:节点13——>节点20;找到了
example 4:search key = 21