@@ -37,9 +37,6 @@ public SkipList()
37
37
_currentMaxLevel = 1 ;
38
38
_randomizer = new Random ( ) ;
39
39
_firstNode = new SkipListNode < T > ( default ( T ) , MaxLevel ) ;
40
-
41
- for ( int i = 0 ; i < MaxLevel ; ++ i )
42
- _firstNode . Forwards [ i ] = _firstNode ;
43
40
}
44
41
45
42
@@ -98,36 +95,43 @@ public void Add(T item)
98
95
var current = _firstNode ;
99
96
var toBeUpdated = new SkipListNode < T > [ MaxLevel ] ;
100
97
98
+ // Get nodes for updated
101
99
for ( int i = _currentMaxLevel - 1 ; i >= 0 ; -- i )
102
100
{
103
- while ( current . Forwards [ i ] != _firstNode && current . Forwards [ i ] . Value . IsLessThan ( item ) )
101
+ while ( current . Forwards [ i ] != null && current . Forwards [ i ] . Value . IsLessThan ( item ) )
102
+ {
104
103
current = current . Forwards [ i ] ;
104
+ }
105
105
106
106
toBeUpdated [ i ] = current ;
107
107
}
108
108
109
- // Get the next node level, and update list level if required.
110
- int lvl = _getNextLevel ( ) ;
111
- if ( lvl > _currentMaxLevel )
109
+ // Desired position to insert key
110
+ current = current . Forwards [ 0 ] ;
111
+
112
+ if ( current == null || ! current . Value . Equals ( item ) )
112
113
{
113
- for ( int i = _currentMaxLevel ; i < lvl ; ++ i )
114
- toBeUpdated [ i ] = _firstNode ;
114
+ // Get the next node level, and update list level if required.
115
+ int lvl = _getNextLevel ( ) ;
116
+ if ( lvl > _currentMaxLevel )
117
+ {
118
+ for ( int i = _currentMaxLevel ; i < lvl ; ++ i )
119
+ toBeUpdated [ i ] = _firstNode ;
115
120
116
- _currentMaxLevel = lvl ;
117
- }
121
+ _currentMaxLevel = lvl ;
122
+ }
118
123
119
- // New node
120
- var newNode = new SkipListNode < T > ( item , lvl ) ;
124
+ var newNode = new SkipListNode < T > ( item , lvl ) ;
121
125
122
- // Insert the new node into the skip list
123
- for ( int i = 0 ; i < lvl ; ++ i )
124
- {
125
- newNode . Forwards [ i ] = toBeUpdated [ i ] . Forwards [ i ] ;
126
- toBeUpdated [ i ] . Forwards [ i ] = newNode ;
127
- }
126
+ // Insert the new node into the skip list
127
+ for ( int i = 0 ; i < lvl ; ++ i )
128
+ {
129
+ newNode . Forwards [ i ] = toBeUpdated [ i ] . Forwards [ i ] ;
130
+ toBeUpdated [ i ] . Forwards [ i ] = newNode ;
131
+ }
128
132
129
- // Increment the count
130
- ++ _count ;
133
+ ++ _count ;
134
+ }
131
135
}
132
136
133
137
/// <summary>
@@ -151,7 +155,7 @@ public bool Remove(T item, out T deleted)
151
155
// Mark all nodes as toBeUpdated.
152
156
for ( int i = _currentMaxLevel - 1 ; i >= 0 ; -- i )
153
157
{
154
- while ( current . Forwards [ i ] != _firstNode && current . Forwards [ i ] . Value . IsLessThan ( item ) )
158
+ while ( current . Forwards [ i ] != null && current . Forwards [ i ] . Value . IsLessThan ( item ) )
155
159
current = current . Forwards [ i ] ;
156
160
157
161
toBeUpdated [ i ] = current ;
@@ -160,7 +164,7 @@ public bool Remove(T item, out T deleted)
160
164
current = current . Forwards [ 0 ] ;
161
165
162
166
// Return default value of T if the item was not found
163
- if ( current . Value . IsEqualTo ( item ) == false )
167
+ if ( current == null || current . Value . IsEqualTo ( item ) == false )
164
168
{
165
169
deleted = default ( T ) ;
166
170
return false ;
@@ -170,18 +174,20 @@ public bool Remove(T item, out T deleted)
170
174
// Unlink it from the levels where it exists.
171
175
for ( int i = 0 ; i < _currentMaxLevel ; ++ i )
172
176
{
173
- if ( toBeUpdated [ i ] . Forwards [ i ] = = current )
177
+ if ( toBeUpdated [ i ] . Forwards [ i ] ! = current )
174
178
{
175
- toBeUpdated [ i ] . Forwards [ i ] = current . Forwards [ i ] ;
179
+ break ;
176
180
}
181
+
182
+ toBeUpdated [ i ] . Forwards [ i ] = current . Forwards [ i ] ;
177
183
}
178
184
179
185
// Decrement the count
180
186
-- _count ;
181
187
182
188
// Check to see if we've deleted the highest-level node
183
189
// Decrement level
184
- while ( _currentMaxLevel > 1 && _firstNode . Forwards [ _currentMaxLevel - 1 ] == _firstNode )
190
+ while ( _currentMaxLevel > 1 && _firstNode . Forwards [ _currentMaxLevel - 1 ] == null )
185
191
-- _currentMaxLevel ;
186
192
187
193
// Assign the deleted output parameter to the node.Value
@@ -194,8 +200,7 @@ public bool Remove(T item, out T deleted)
194
200
/// </summary>
195
201
public bool Contains ( T item )
196
202
{
197
- T itemOut ;
198
- return Find ( item , out itemOut ) ;
203
+ return Find ( item , out var _ ) ;
199
204
}
200
205
201
206
/// <summary>
@@ -207,13 +212,13 @@ public bool Find(T item, out T result)
207
212
208
213
// Walk after all the nodes that have values less than the node we are looking for
209
214
for ( int i = _currentMaxLevel - 1 ; i >= 0 ; -- i )
210
- while ( current . Forwards [ i ] != _firstNode && current . Forwards [ i ] . Value . IsLessThan ( item ) )
215
+ while ( current . Forwards [ i ] != null && current . Forwards [ i ] . Value . IsLessThan ( item ) )
211
216
current = current . Forwards [ i ] ;
212
217
213
218
current = current . Forwards [ 0 ] ;
214
219
215
220
// Return true if we found the element; false otherwise
216
- if ( current . Value . IsEqualTo ( item ) )
221
+ if ( current != null && current . Value . IsEqualTo ( item ) )
217
222
{
218
223
result = current . Value ;
219
224
return true ;
@@ -290,7 +295,7 @@ public bool TryPeek(out T result)
290
295
public IEnumerator < T > GetEnumerator ( )
291
296
{
292
297
var node = _firstNode ;
293
- while ( node . Forwards [ 0 ] != null && node . Forwards [ 0 ] != _firstNode )
298
+ while ( node . Forwards [ 0 ] != null && node . Forwards [ 0 ] != null )
294
299
{
295
300
node = node . Forwards [ 0 ] ;
296
301
yield return node . Value ;
@@ -349,9 +354,6 @@ public void Clear()
349
354
_currentMaxLevel = 1 ;
350
355
_randomizer = new Random ( ) ;
351
356
_firstNode = new SkipListNode < T > ( default ( T ) , MaxLevel ) ;
352
-
353
- for ( int i = 0 ; i < MaxLevel ; ++ i )
354
- _firstNode . Forwards [ i ] = _firstNode ;
355
357
}
356
358
#endregion
357
359
@@ -364,7 +366,9 @@ private int _getNextLevel()
364
366
int lvl = 1 ;
365
367
366
368
while ( _randomizer . NextDouble ( ) < Probability && lvl <= _currentMaxLevel && lvl < MaxLevel )
369
+ {
367
370
++ lvl ;
371
+ }
368
372
369
373
return lvl ;
370
374
}
0 commit comments