前提:有序数据 + 基于链表
操作:有序数据的查询 + 插入 + 删除
时间复杂度:O(logn)
思想:将有序数据进行分层,最底层是存储所有的数据,之后每一层逐层减少数据,并且需要注意 每一层的数据是基于其前一层的数据随机而来
。(这里有一个点需要注意:这种随机可能会造成上层的数据失控,因此是实现时一般会做一定的 数据数量限制的伪随机 / 动态的变化概率
防止出现数据失控,造成数据太少或太多)
举例:
现有数据(设定总共 3 层):1 -> 2 -> 5 -> 7 ->14 -> 23 -> 47
则分层完成后结果如下(每一层的每一个值是通过设定的概率筛选出来的):
第 0 层:1 -> 2 -> 5 -> 7 ->14 -> 23 -> 47
第 1 层:1 -> 5 -> 7 -> 23
第 2 层:1 -> 23
- 查询逻辑:每次查询都从顶层开始查询,并且降层时是从本层现校验的元素开始筛选而不是从头开始。
现在查询 14:
-1-:首先查询第 2 层,发现比 1 大比 23 小,开始查询第 1 层
-2-:从 1 开始查询第 1 层,发现比最后一个值 23 小,开始查询第 0 层
-3-:从 7 开始查询第 0 层,发现 7 的下一个值就是 14,查询完成 - 插入数据逻辑:每次从最底层开始插入
首先插入第 0 层
对应的位置,然后根据设定的概率判断是否要升层,如果升层则每一层都做同样的判断直到到达最顶层或者不需要升层为止。 - 删除数据逻辑:从顶层开始逐层查询元素删除
首先从第 2 层开始查询,如果查询到了则删除,然后依次降层查询删除。
实现:
接下来用python3来实现一下跳表(该实现没做伪随机,有一定概率出现上层数据失控):
import randomclass SkipListNode:def __init__(self, key, level):self.key = keyself.forward = [None] * (level + 1)class SkipList:def __init__(self, max_level, p):self.max_level = max_level # 最大层数self.p = p # 向上提升一个级别的概率self.header = SkipListNode(None, max_level) # 创建头节点self.level = 0 # 当前最高层数def random_level(self):level = 0while random.random() < self.p and level < self.max_level:level += 1return leveldef insert(self, key):update = [None] * (self.max_level + 1)current = self.header# 从最高层开始,找到每层中小于插入键的最大键for i in range(self.level, -1, -1):while current.forward[i] and current.forward[i].key < key:current = current.forward[i]update[i] = current# 移动到下一层current = current.forward[0]# 如果当前层没有该键,则插入if current is None or current.key != key:# 随机确定节点高度rlevel = self.random_level()# 如果新节点的层数更高if rlevel > self.level:for i in range(self.level + 1, rlevel + 1):update[i] = self.headerself.level = rlevel# 创建新节点n = SkipListNode(key, rlevel)for i in range(rlevel + 1):n.forward[i] = update[i].forward[i]update[i].forward[i] = ndef search(self, key):current = self.headerfor i in range(self.level, -1, -1):while current.forward[i] and current.forward[i].key < key:current = current.forward[i]current = current.forward[0]if current and current.key == key:return Truereturn Falsedef display(self):print("Skip List")for i in range(self.level + 1):print("Level {}: ".format(i), end="")node = self.header.forward[i]while node:print(node.key, end=" ")node = node.forward[i]print("")# 创建跳表实例,最大层设为3,提升概率为0.5(这个概率随便设置)
skip_list = SkipList(3, 0.5)
skip_list.insert(3)
skip_list.insert(6)
skip_list.insert(7)
skip_list.insert(9)
skip_list.insert(12)
skip_list.insert(19)
skip_list.insert(17)# 显示跳表
skip_list.display()# 搜索元素
print("Search for 6:", skip_list.search(6))
print("Search for 15:", skip_list.search(15))
本文完~