@@ -17,7 +17,7 @@ public class SkipList<T extends Comparable<T>> implements ISet<T> {
17
17
18
18
private static final Random seedGenerator = new Random ();
19
19
20
- // Defaults
20
+ // If you change this number, you also need to change the random function.
21
21
private static final int MAX = 31 ;
22
22
23
23
private int randomSeed = -1 ;
@@ -60,21 +60,23 @@ private Node<T> insertValue(T value) {
60
60
// handle case where head is greater than new node, just swap values
61
61
T oldHeadValue = head .value ;
62
62
head .value = value ;
63
+ // Swap the old head value into the new node
63
64
node .value = oldHeadValue ;
64
65
}
66
+ // Start from the top and work down to update the pointers
65
67
for (int i =MAX ; i >=0 ; i --) {
66
68
Node <T > next = prev .getNext (i );
67
69
while (next !=null ) {
68
70
if (next .value .compareTo (value )==1 ) break ;
69
71
prev = next ;
72
+ // It's important to set next since the node we are looking for
73
+ // on the next level cannot be behind this "prev" node.
70
74
next = prev .getNext (i );
71
75
}
72
76
if (i <= level ) {
77
+ // If we are on a level where the new node exists, update the linked list
73
78
node .setNext (i , next );
74
- if (next !=null ) next .setPrev (i , node );
75
-
76
79
prev .setNext (i , node );
77
- node .setPrev (i , prev );
78
80
}
79
81
}
80
82
}
@@ -91,13 +93,13 @@ public boolean add(T value) {
91
93
return (node !=null );
92
94
}
93
95
94
- private Node <T > findValue (T value ) {
96
+ private NodeLevelPair <T > findPredecessor (T value ) {
95
97
Node <T > node = head ;
96
98
if (node ==null ) return null ;
97
- else if (node .value .equals (value )) return node ;
99
+ if (node .value .equals (value )) return null ;
98
100
99
- // Current node is not the node we are looking for. Keep moving down
100
- // until you find a node with a "next" node .
101
+ // Current node is not the node we are looking for; Keep moving down
102
+ // until you find a node with a non-null "next" pointer .
101
103
int level = node .getLevel ();
102
104
Node <T > next = node .getNext (level );
103
105
while (next ==null ) {
@@ -110,8 +112,9 @@ private Node<T> findValue(T value) {
110
112
while (next !=null ) {
111
113
int comp = next .value .compareTo (value );
112
114
if (comp ==0 ) {
113
- // Found the node!
114
- return next ;
115
+ // Found the node who's next node is the node we are looking for!
116
+ NodeLevelPair <T > pair = new NodeLevelPair <T >(level ,node );
117
+ return pair ;
115
118
} else if (comp ==1 ) {
116
119
// Found a node that's greater, move down a level
117
120
if (level >0 ) level --;
@@ -120,7 +123,7 @@ private Node<T> findValue(T value) {
120
123
// Update the next pointer
121
124
next = node .getNext (level );
122
125
} else {
123
- // Next is less then the value we are looking for, keep moving right .
126
+ // Next is less then the value we are looking for, keep moving to next .
124
127
node = next ;
125
128
next = node .getNext (level );
126
129
while (next ==null && level >0 ) {
@@ -131,30 +134,73 @@ private Node<T> findValue(T value) {
131
134
return null ;
132
135
}
133
136
137
+ private Node <T > findValue (T value ) {
138
+ if (head ==null ) return null ;
139
+ if (head .value .compareTo (value )==0 ) return head ;
140
+
141
+ NodeLevelPair <T > pair = findPredecessor (value );
142
+ if (pair ==null ) return null ;
143
+ return pair .node .getNext (pair .level );
144
+ }
145
+
134
146
private Node <T > removeValue (T value ) {
135
- Node <T > node = findValue (value );
136
- if (node ==null ) return null ;
137
-
138
- Node <T > prev = node .getPrev (0 );
139
- Node <T > next = node .getNext (0 );
147
+ Node <T > node = null ;
148
+ Node <T > prev = null ;
149
+ int lvl = 0 ;
150
+ // Find the predecessor of the node we are looking for and
151
+ // which level it is found on.
152
+ NodeLevelPair <T > pair = findPredecessor (value );
153
+ if (pair !=null ) {
154
+ prev = pair .node ;
155
+ lvl = pair .level ;
156
+ }
157
+
158
+ // Head node has no predecessor
159
+ if (prev ==null )
160
+ node = head ;
161
+ else
162
+ node = prev .getNext (lvl );
163
+
164
+ // Either head is null or node doesn't exist
165
+ if (node == null )
166
+ return null ;
167
+
168
+ Node <T > next = null ;
169
+ // Head node is the only node without a prev node
140
170
if (prev == null ) {
171
+ next = node .getNext (0 );
141
172
// Removing head
142
173
if (next != null ) {
174
+ // Switch the value of the next into the head node
143
175
node .value = next .value ;
144
176
next .value = value ;
177
+ // Update the prev and node pointer
178
+ prev = node ;
145
179
node = next ;
146
180
} else {
181
+ // If head doesn't have a new node then list is empty
147
182
head = null ;
148
183
}
184
+ } else {
185
+ // Set the next node pointer
186
+ next = node .getNext (lvl );
149
187
}
188
+
189
+ // Start from the top level and move down removing the node
150
190
int level = node .getLevel ();
151
191
for (int i =level ; i >=0 ; i --) {
152
- prev = node .getPrev (i );
153
192
next = node .getNext (i );
154
- if (prev != null )
193
+ if (prev != null ) {
155
194
prev .setNext (i , next );
156
- if (next != null )
157
- next .setPrev (i , prev );
195
+ if (i > 0 ) {
196
+ // Move down a level and look for the 'next' previous node
197
+ Node <T > temp = prev .getNext (i - 1 );
198
+ while (temp != null && temp .value .compareTo (value ) != 0 ) {
199
+ prev = temp ;
200
+ temp = temp .getNext (i - 1 );
201
+ }
202
+ }
203
+ }
158
204
}
159
205
size --;
160
206
return node ;
@@ -204,10 +250,6 @@ public boolean validate() {
204
250
}
205
251
prev = node ;
206
252
node = node .getNext (i );
207
- if (node != null && !node .getPrev (i ).value .equals (prev .value )) {
208
- System .err .println ("prev!=next" );
209
- return false ;
210
- }
211
253
}
212
254
}
213
255
return true ;
@@ -267,18 +309,16 @@ public String toString() {
267
309
268
310
private static final class Node <T extends Comparable <T >> {
269
311
270
- private Node <T >[] prev = null ;
271
312
private Node <T >[] next = null ;
272
313
private T value = null ;
273
314
274
315
private Node (int level , T data ) {
275
- this .prev = new Node [level +1 ];
276
316
this .next = new Node [level +1 ];
277
317
this .value = data ;
278
318
}
279
319
280
320
private int getLevel () {
281
- return prev .length -1 ;
321
+ return next .length -1 ;
282
322
}
283
323
284
324
private void setNext (int idx , Node <T > node ) {
@@ -289,32 +329,14 @@ private Node<T> getNext(int idx) {
289
329
return this .next [idx ];
290
330
}
291
331
292
- private void setPrev (int idx , Node <T > node ) {
293
- this .prev [idx ] = node ;
294
- }
295
- private Node <T > getPrev (int idx ) {
296
- if (idx >=this .prev .length ) return null ;
297
- return this .prev [idx ];
298
- }
299
-
300
332
/**
301
333
* {@inheritDoc}
302
334
*/
303
335
@ Override
304
336
public String toString () {
305
337
StringBuilder builder = new StringBuilder ();
306
338
builder .append ("data=" ).append (value );
307
- int size = prev .length ;
308
- if (prev !=null ) {
309
- builder .append ("\n " ).append ("prev=[" );
310
- for (int i =0 ; i <size ; i ++) {
311
- Node <T > n = prev [i ];
312
- if (n !=null ) builder .append (n .value );
313
- else builder .append ("none" );
314
- if (i !=size -1 ) builder .append ("<-" );
315
- }
316
- builder .append ("]" );
317
- }
339
+ int size = next .length ;
318
340
if (next !=null ) {
319
341
builder .append ("\n " ).append ("next=[" );
320
342
for (int i =0 ; i <size ; i ++) {
@@ -329,6 +351,15 @@ public String toString() {
329
351
}
330
352
}
331
353
354
+ private static final class NodeLevelPair <T extends Comparable <T >> {
355
+ private int level = -1 ;
356
+ private Node <T > node = null ;
357
+ private NodeLevelPair (int level , Node <T > node ) {
358
+ this .level = level ;
359
+ this .node = node ;
360
+ }
361
+ }
362
+
332
363
public static class JavaCompatibleSkipList <T extends Comparable <T >> extends java .util .AbstractSet <T > {
333
364
334
365
private SkipList <T > list = null ;
0 commit comments