1、 跳表--skiplist
skiplist本质上是一种查找结构,跟平衡搜索树和哈希表的价值是一样的。跳表首先是一个链表,它是在链表的基础上发展的。但一般的链表进行查找数据只能全部遍历,时间复杂度为O(n)。
William Pugh的优化:
- 假如每相邻两个节点升高一层,增加一个指针,让该指针指向下下个节点。
所有新增加的指针连成了一个新的链表,由于新增加的指针,我们不再需要与链表中每个节点逐个进行比较了,需要比较的节点数大概只有原来的一半。
- 在第二层新产生的链表上,继续为每相邻的两个节点升高一层,增加一个指针,从而产生第三层链表。查找效率可以进一步提升
- 按照上面生成链表的方式,上面每一层链表的节点个数,是下面一层的节点个数的一半,这样查找过程就非常类似二分查找,使得查找的时间复杂度可以降低到O(log n)
但问题在于在插入或者删除时,如果严格遵守上述规则就需要把后续被影响的节点的指向全部修改,就又需要重新遍历一遍。时间复杂度又上升为O(n)。
- William Pugh做了一个大胆的处理,不再严格要求对应比例关系,而是插入一个节点的时候随机出一个层数。这样每次插入和删除都不需要考虑其他节点的层数。
2、 随机的层数
一般跳表会设计一个最大层数maxLevel的限制,其次会设置一个多增加一层的概率p。那么计算这个随机层数的伪代码如下图: