@@ -17,7 +17,7 @@ public class SkipList<T extends Comparable<T>> implements ISet<T> {
1717
1818 private static final Random seedGenerator = new Random ();
1919
20- // Defaults
20+ // If you change this number, you also need to change the random function.
2121 private static final int MAX = 31 ;
2222
2323 private int randomSeed = -1 ;
@@ -60,21 +60,23 @@ private Node<T> insertValue(T value) {
6060 // handle case where head is greater than new node, just swap values
6161 T oldHeadValue = head .value ;
6262 head .value = value ;
63+ // Swap the old head value into the new node
6364 node .value = oldHeadValue ;
6465 }
66+ // Start from the top and work down to update the pointers
6567 for (int i =MAX ; i >=0 ; i --) {
6668 Node <T > next = prev .getNext (i );
6769 while (next !=null ) {
6870 if (next .value .compareTo (value )==1 ) break ;
6971 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.
7074 next = prev .getNext (i );
7175 }
7276 if (i <= level ) {
77+ // If we are on a level where the new node exists, update the linked list
7378 node .setNext (i , next );
74- if (next !=null ) next .setPrev (i , node );
75-
7679 prev .setNext (i , node );
77- node .setPrev (i , prev );
7880 }
7981 }
8082 }
@@ -91,13 +93,13 @@ public boolean add(T value) {
9193 return (node !=null );
9294 }
9395
94- private Node <T > findValue (T value ) {
96+ private NodeLevelPair <T > findPredecessor (T value ) {
9597 Node <T > node = head ;
9698 if (node ==null ) return null ;
97- else if (node .value .equals (value )) return node ;
99+ if (node .value .equals (value )) return null ;
98100
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 .
101103 int level = node .getLevel ();
102104 Node <T > next = node .getNext (level );
103105 while (next ==null ) {
@@ -110,8 +112,9 @@ private Node<T> findValue(T value) {
110112 while (next !=null ) {
111113 int comp = next .value .compareTo (value );
112114 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 ;
115118 } else if (comp ==1 ) {
116119 // Found a node that's greater, move down a level
117120 if (level >0 ) level --;
@@ -120,7 +123,7 @@ private Node<T> findValue(T value) {
120123 // Update the next pointer
121124 next = node .getNext (level );
122125 } 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 .
124127 node = next ;
125128 next = node .getNext (level );
126129 while (next ==null && level >0 ) {
@@ -131,30 +134,73 @@ private Node<T> findValue(T value) {
131134 return null ;
132135 }
133136
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+
134146 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
140170 if (prev == null ) {
171+ next = node .getNext (0 );
141172 // Removing head
142173 if (next != null ) {
174+ // Switch the value of the next into the head node
143175 node .value = next .value ;
144176 next .value = value ;
177+ // Update the prev and node pointer
178+ prev = node ;
145179 node = next ;
146180 } else {
181+ // If head doesn't have a new node then list is empty
147182 head = null ;
148183 }
184+ } else {
185+ // Set the next node pointer
186+ next = node .getNext (lvl );
149187 }
188+
189+ // Start from the top level and move down removing the node
150190 int level = node .getLevel ();
151191 for (int i =level ; i >=0 ; i --) {
152- prev = node .getPrev (i );
153192 next = node .getNext (i );
154- if (prev != null )
193+ if (prev != null ) {
155194 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+ }
158204 }
159205 size --;
160206 return node ;
@@ -204,10 +250,6 @@ public boolean validate() {
204250 }
205251 prev = node ;
206252 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- }
211253 }
212254 }
213255 return true ;
@@ -267,18 +309,16 @@ public String toString() {
267309
268310 private static final class Node <T extends Comparable <T >> {
269311
270- private Node <T >[] prev = null ;
271312 private Node <T >[] next = null ;
272313 private T value = null ;
273314
274315 private Node (int level , T data ) {
275- this .prev = new Node [level +1 ];
276316 this .next = new Node [level +1 ];
277317 this .value = data ;
278318 }
279319
280320 private int getLevel () {
281- return prev .length -1 ;
321+ return next .length -1 ;
282322 }
283323
284324 private void setNext (int idx , Node <T > node ) {
@@ -289,32 +329,14 @@ private Node<T> getNext(int idx) {
289329 return this .next [idx ];
290330 }
291331
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-
300332 /**
301333 * {@inheritDoc}
302334 */
303335 @ Override
304336 public String toString () {
305337 StringBuilder builder = new StringBuilder ();
306338 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 ;
318340 if (next !=null ) {
319341 builder .append ("\n " ).append ("next=[" );
320342 for (int i =0 ; i <size ; i ++) {
@@ -329,6 +351,15 @@ public String toString() {
329351 }
330352 }
331353
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+
332363 public static class JavaCompatibleSkipList <T extends Comparable <T >> extends java .util .AbstractSet <T > {
333364
334365 private SkipList <T > list = null ;
0 commit comments