11import math
22
33
4+ class Node :
5+ def __init__ (self , value , next = None ):
6+ self .value = value
7+ self .next = next
8+
9+
410class SkipList :
511 def __init__ (self ):
6- self .data = [] # sorted list
12+ self .head = None
13+ self .length = 0
714 self .skips = [] # list of skip pointers, each is a tuple (index, value)
815
16+ def _get_node (self , index ):
17+ """Get the node at the given index."""
18+ current = self .head
19+ for _ in range (index ):
20+ if current is None :
21+ return None
22+ current = current .next
23+ return current
24+
925 def rebuild_skips (self ):
1026 """Rebuild the skip pointer so we can jump over sqrt(n) elements."""
11- n = len ( self .data )
27+ n = self .length
1228 if n == 0 :
1329 self .skips = []
1430 return
@@ -18,49 +34,95 @@ def rebuild_skips(self):
1834
1935 def _find_position (self , value ):
2036 """Find the position to insert value using skip pointers."""
21- if not self .data :
37+ if self .length == 0 :
2238 return 0
2339
2440 # Use skip pointers to find the range where value should be
2541 for i in range (len (self .skips ) - 1 ):
2642 a = self .skips [i ]
2743 b = self .skips [i + 1 ]
28- if self .data [a ] <= value < self .data [b ]:
44+
45+ node_a = self ._get_node (a )
46+ node_b = self ._get_node (b )
47+
48+ if node_a .value <= value < node_b .value :
2949 # linear search between a and b
30- for j in range (a , b ):
31- if self .data [j ] >= value :
32- return j
50+ idx = a
51+ current = node_a
52+ while idx < b and current :
53+ if current .value >= value :
54+ return idx
55+ current = current .next
56+ idx += 1
3357 return b
34-
3558 # Check the last skip pointer
3659 start = self .skips [- 1 ]
37- for j in range (start , len (self .data )):
38- if self .data [j ] >= value :
39- return j
40- return len (self .data )
60+ idx = start
61+ current = self ._get_node (start )
62+ while current :
63+ if current .value >= value :
64+ return idx
65+ current = current .next
66+ idx += 1
67+ return self .length
4168
4269 def insert (self , value ):
4370 """Insert value into the skip list, maintaining sorted order."""
4471 pos = self ._find_position (value )
4572
46- if pos < len (self .data ) and self .data [pos ] == value :
47- return # value already exists, do not insert duplicates
48- self .data .insert (pos , value )
73+ if pos < self .length :
74+ node_at_pos = self ._get_node (pos )
75+ if node_at_pos and node_at_pos .value == value :
76+ return # value already exists, do not insert duplicates
77+ # Insert the new node
78+ new_node = Node (value )
79+ if pos == 0 :
80+ new_node .next = self .head
81+ self .head = new_node
82+ else :
83+ prev_node = self ._get_node (pos - 1 )
84+ new_node .next = prev_node .next
85+ prev_node .next = new_node
86+ self .length += 1
4987 self .rebuild_skips ()
5088
5189 def __contains__ (self , value ):
52- if not self .data :
90+ if self .length == 0 :
5391 return False
5492
5593 for i in range (len (self .skips ) - 1 ):
5694 a = self .skips [i ]
5795 b = self .skips [i + 1 ]
58- if self .data [a ] <= value < self .data [b ]:
59- return value in self .data [a :b ]
6096
97+ node_a = self ._get_node (a )
98+ node_b = self ._get_node (b )
99+
100+ if node_a .value <= value < node_b .value :
101+ idx = a
102+ current = node_a
103+ while idx < b and current :
104+ if current .value == value :
105+ return True
106+ current = current .next
107+ idx += 1
108+ return False
61109 start = self .skips [- 1 ]
62- return value in self .data [start ::]
110+ idx = start
111+ current = self ._get_node (start )
112+
113+ while current :
114+ if current .value == value :
115+ return True
116+ current = current .next
117+ idx += 1
118+
119+ return False
63120
64121 def to_list (self ):
65122 """Return the skip list as a regular sorted list."""
66- return self .data
123+ result = []
124+ current = self .head
125+ while current :
126+ result .append (current .value )
127+ current = current .next
128+ return result
0 commit comments