Skip to content

Commit db405a1

Browse files
committed
fix: use skip list nodes instead of list.insert for O(log n) insertion
1 parent 775ae3c commit db405a1

File tree

1 file changed

+57
-25
lines changed

1 file changed

+57
-25
lines changed
Lines changed: 57 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,69 @@
1+
import random
2+
3+
4+
class SkipListNode:
5+
"""Node in a skip list with multiple forward pointers"""
6+
def __init__(self, value, levels):
7+
self.value = value
8+
self.forward = [None] * levels
9+
10+
111
class SkipList:
212
def __init__(self):
3-
self.data = []
13+
self.max_level = 16
14+
self.head = SkipListNode(float('-inf'), self.max_level)
15+
self.level = 0
16+
17+
def _random_level(self):
18+
"""Generate random level for a new node (coin flip)"""
19+
level = 0
20+
while random.random() < 0.5 and level < self.max_level - 1:
21+
level += 1
22+
return level
423

524
def insert(self, value):
6-
"""Insert value in sorted order"""
7-
# Find insertion point
8-
left, right = 0, len(self.data)
9-
while left < right:
10-
mid = (left + right) // 2
11-
if self.data[mid] < value:
12-
left = mid + 1
13-
else:
14-
right = mid
25+
"""Insert value in sorted order - O(log n) time complexity"""
26+
update = [None] * self.max_level
27+
current = self.head
28+
29+
for i in range(self.level, -1, -1):
30+
while current.forward[i] and current.forward[i].value < value:
31+
current = current.forward[i]
32+
update[i] = current
33+
34+
current = current.forward[0]
35+
new_level = self._random_level()
36+
37+
if new_level > self.level:
38+
for i in range(self.level + 1, new_level + 1):
39+
update[i] = self.head
40+
self.level = new_level
1541

16-
# Insert at found position
17-
self.data.insert(left, value)
42+
new_node = SkipListNode(value, new_level + 1)
43+
44+
for i in range(new_level + 1):
45+
new_node.forward[i] = update[i].forward[i]
46+
update[i].forward[i] = new_node
1847

1948
def contains(self, value) -> bool:
20-
"""Check if value exists"""
21-
left, right = 0, len(self.data)
22-
while left < right:
23-
mid = (left + right) // 2
24-
if self.data[mid] == value:
25-
return True
26-
elif self.data[mid] < value:
27-
left = mid + 1
28-
else:
29-
right = mid
30-
return False
49+
"""Check if value exists - O(log n) time complexity"""
50+
current = self.head
51+
52+
for i in range(self.level, -1, -1):
53+
while current.forward[i] and current.forward[i].value < value:
54+
current = current.forward[i]
55+
56+
current = current.forward[0]
57+
return current is not None and current.value == value
3158

3259
def to_list(self) -> list:
33-
"""Convert to sorted list"""
34-
return self.data.copy()
60+
"""Convert to sorted list - O(n) time complexity"""
61+
result = []
62+
current = self.head.forward[0]
63+
while current:
64+
result.append(current.value)
65+
current = current.forward[0]
66+
return result
3567

3668
def __contains__(self, value) -> bool:
3769
return self.contains(value)

0 commit comments

Comments
 (0)