结构:
多层链表结构,每层是有序的
工作原理 :
- 最底层包含所有元素,按分数排序
- 上层为"快速通道",包含部分元素
- 查找时从顶层开始,逐步降级,类似二分查找
优势 :
- 插入/删除/查找:O(log N)
- 实现简单,比平衡树更容易维护
- 并发性能好,无需复杂的锁机制
代码实现:
python
class SkipListNode:
"""跳表节点"""
def __init__(self, key: float, value: Any, level: int):
self.key = key # 排序键
self.value = value # 存储的值
self.forward = [None] * (level + 1) # 每层的前向指针
class SkipList:
"""跳表实现"""
def __init__(self, max_level: int = 16, p: float = 0.5):
"""
初始化跳表
Args:
max_level: 最大层数
p: 晋升概率
"""
self.max_level = max_level
self.p = p
self.level = 0 # 当前最大层数
self.header = SkipListNode(float('-inf'), None, max_level) # 头节点
def random_level(self) -> int:
"""
随机生成节点层数
遵循几何分布,概率为 p^level
"""
level = 0
while random.random() < self.p and level < self.max_level:
level += 1
return level
def search(self, key: float) -> Optional[Any]:
"""
查找指定键的值
Args:
key: 要查找的键
Returns:
找到的值,未找到返回None
"""
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]
# 到达第0层,检查是否找到
current = current.forward[0]
if current and current.key == key:
return current.value
return None
def insert(self, key: float, value: Any) -> None:
"""
插入键值对
Args:
key: 键
value: 值
"""
# 记录每层的插入位置
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
# 生成随机层数
new_level = self.random_level()
# 更新跳表当前最大层数
if new_level > self.level:
for i in range(self.level + 1, new_level + 1):
update[i] = self.header
self.level = new_level
# 创建新节点
new_node = SkipListNode(key, value, new_level)
# 更新各层的指针
for i in range(new_level + 1):
new_node.forward[i] = update[i].forward[i]
update[i].forward[i] = new_node
def delete(self, key: float) -> bool:
"""
删除指定键
Args:
key: 要删除的键
Returns:
是否删除成功
"""
# 记录每层的删除位置
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
# 到达第0层,检查是否找到
current = current.forward[0]
if not current or current.key != key:
return False
# 更新各层的指针
for i in range(self.level + 1):
if update[i].forward[i] != current:
break
update[i].forward[i] = current.forward[i]
# 更新跳表当前最大层数
while self.level > 0 and not self.header.forward[self.level]:
self.level -= 1
return True
def range_query(self, start: float, end: float) -> List[Tuple[float, Any]]:
"""
范围查询
Args:
start: 起始键
end: 结束键
Returns:
键值对列表
"""
result = []
current = self.header
# 从最高层开始查找起始位置
for i in range(self.level, -1, -1):
while current.forward[i] and current.forward[i].key < start:
current = current.forward[i]
# 从起始位置开始收集结果
current = current.forward[0]
while current and current.key <= end:
result.append((current.key, current.value))
current = current.forward[0]
return result
def get_all(self) -> List[Tuple[float, Any]]:
"""
获取所有键值对
Returns:
键值对列表
"""
result = []
current = self.header.forward[0]
while current:
result.append((current.key, current.value))
current = current.forward[0]
return result
def __str__(self) -> str:
"""
字符串表示
"""
result = []
for i in range(self.level, -1, -1):
level_str = f"Level {i}: "
current = self.header.forward[i]
nodes = []
while current:
nodes.append(f"({current.key}, {current.value})")
current = current.forward[i]
level_str += " -> ".join(nodes)
result.append(level_str)
return "\n".join(result)