77import com .jwetherell .algorithms .data_structures .interfaces .IList ;
88
99/**
10- * A treap is a self-balancing binary search tree that
11- * uses randomization to maintain a low height. In this version,
12- * it is used emulate the operations of an array and linked list.
10+ * A Treap is a self-balancing binary search tree that uses randomization to maintain
11+ * a low height. In this version, it is used emulate the operations of an array and linked list.
1312 *
14- * Time Complexity: Assuming the join functions have constant complexity:
15- * insert( ), push_back( ), erase( ), at( ), modify(), and query() are all
16- * O(log N ), while walk() is O(N).
13+ * Time Complexity: Assuming the join/merge functions have constant complexity.
14+ * add(value ), add(index,value ), remove(index ), set(index,value ), get(index) all have O(log N).
15+ * remove(value), get(value ), contains(value) all have O(N).
1716 *
18- * Space Complexity: O(N) on the size of the array.
17+ * Space Complexity: O(N)
1918 *
2019 * Note: This implementation is 0-based, meaning that all
2120 * indices from 0 to size() - 1, inclusive, are accessible.
@@ -56,9 +55,8 @@ public ImplicitKeyTreap(int randomSeed) {
5655 */
5756 @ Override
5857 public boolean add (T value ) {
59- final int s = size ;
60- add (s , value );
61- return (size ==s +1 );
58+ final T t = add (size , value );
59+ return (t !=null );
6260 }
6361
6462 /**
@@ -67,19 +65,22 @@ public boolean add(T value) {
6765 * @param index to insert value
6866 * @param value to insert
6967 */
70- public void add (int index , T value ) {
71- root = insert (((Node <T >)root ), index , value );
72- if (root == null )
73- size = 0 ;
74- else
75- size = (((Node <T >)root ).size );
68+ public T add (int index , T value ) {
69+ addAtIndexAndUpdate (index , value );
70+
71+ // Check to make sure value was added
72+ final Node <T > n = getNodeByIndex (index );
73+ if (n == null )
74+ return null ;
75+ return n .value ;
7676 }
7777
7878 /**
7979 * {@inheritDoc}
8080 */
8181 @ Override
8282 public boolean remove (T value ) {
83+ // See if value already exists
8384 final int idx = getIndexByValue (value );
8485 if (idx < 0 )
8586 return false ;
@@ -95,15 +96,12 @@ public boolean remove(T value) {
9596 * @return value or null if not found
9697 */
9798 public T removeAtIndex (int index ) {
99+ // See if index already exists
98100 Node <T > n = getNodeByIndex (index );
99101 if (n == null )
100102 return null ;
101103
102- root = remove (((Node <T >)root ), index );
103- if (root == null )
104- size = 0 ;
105- else
106- size = (((Node <T >)root ).size );
104+ removeAtIndexAndUpdate (index );
107105 return n .value ;
108106 }
109107
@@ -114,7 +112,8 @@ public T removeAtIndex(int index) {
114112 * @return value or null if not found
115113 */
116114 public T set (int index , T value ) {
117- final Node <T > n = this .getNodeByIndex (index );
115+ // See if index already exists
116+ final Node <T > n = getNodeByIndex (index );
118117 if (n == null )
119118 return null ;
120119
@@ -127,7 +126,7 @@ public T set(int index, T value) {
127126 */
128127 @ Override
129128 public boolean contains (T value ) {
130- final Node <T > n = this . getNodeByValue (value );
129+ final Node <T > n = getNodeByValue (value );
131130 return (n !=null );
132131 }
133132
@@ -220,8 +219,24 @@ public Pair<T> split(int index) {
220219 return p ;
221220 }
222221
222+ public void addAtIndexAndUpdate (int index , T value ) {
223+ root = insert (((Node <T >)root ), index , value );
224+ if (root == null )
225+ size = 0 ;
226+ else
227+ size = (((Node <T >)root ).size );
228+ }
229+
230+ private void removeAtIndexAndUpdate (int index ) {
231+ root = remove (((Node <T >)root ), index );
232+ if (root == null )
233+ size = 0 ;
234+ else
235+ size = (((Node <T >)root ).size );
236+ }
237+
223238 private Node <T > getNodeByValue (T value ) {
224- return getNode ( value , root );
239+ return getNodeByValue ( root , value );
225240 }
226241
227242 private Node <T > getNodeByIndex (int index ) {
@@ -242,37 +257,6 @@ private Node<T> getNodeByIndex(int index) {
242257 }
243258 }
244259
245- private static <T > Node <T > getNodeByIndex (Node <T > node , int parentIndex , int index ) {
246- if (node == null )
247- return null ;
248-
249- final Node <T > p = (Node <T >)node .parent ;
250- final Node <T > l = (Node <T >)node .left ;
251- final Node <T > r = (Node <T >)node .right ;
252- final int leftSize = ((l !=null )?l .size :0 );
253- final int rightSize = ((r !=null )?r .size :0 );
254-
255- int idx = Integer .MIN_VALUE ;
256- if (p !=null && node .equals (p .left )) {
257- // left
258- idx = parentIndex - rightSize - 1 ;
259- } else if (p !=null && node .equals (p .right )) {
260- // right
261- idx = leftSize + parentIndex + 1 ;
262- } else {
263- throw new RuntimeException ("I do not have a parent :-(" );
264- }
265-
266- if (idx == index )
267- return node ;
268-
269- if (index <= idx ) {
270- return getNodeByIndex (l , idx , index );
271- } else {
272- return getNodeByIndex (r , idx , index );
273- }
274- }
275-
276260 private int getIndexByValue (T value ) {
277261 final Node <T > node = (Node <T >)root ;
278262 if (value == null || node == null )
@@ -286,11 +270,11 @@ private int getIndexByValue(T value) {
286270 if (value .equals (node .value ))
287271 return idx ;
288272
289- int i = getIndexByValue (value , l , idx );
273+ int i = getIndexByValue (l , idx , value );
290274 if (i >= 0 )
291275 return i ;
292276
293- i = getIndexByValue (value , r , idx );
277+ i = getIndexByValue (r , idx , value );
294278 return i ;
295279 }
296280
@@ -373,20 +357,51 @@ private static <T> Node<T> remove(Node<T> root, int index) {
373357 return merge (p .left , (split (p .right , (index + 1 - leftSize ))).right );
374358 }
375359
376- private static <T > Node <T > getNode ( T value , Node <T > node ) {
360+ private static <T > Node <T > getNodeByValue ( Node <T > node , T value ) {
377361 if (node == null )
378362 return null ;
379363
380364 if (node .value .equals (value ))
381365 return node ;
382366
383- Node <T > n = getNode ( value , node .left );
367+ Node <T > n = getNodeByValue ( node .left , value );
384368 if (n == null )
385- n = getNode ( value , node .right );
369+ n = getNodeByValue ( node .right , value );
386370 return n ;
387371 }
388372
389- private static <T > int getIndexByValue (T value , Node <T > node , int parentIndex ) {
373+ private static <T > Node <T > getNodeByIndex (Node <T > node , int parentIndex , int index ) {
374+ if (node == null )
375+ return null ;
376+
377+ final Node <T > p = (Node <T >)node .parent ;
378+ final Node <T > l = (Node <T >)node .left ;
379+ final Node <T > r = (Node <T >)node .right ;
380+ final int leftSize = ((l !=null )?l .size :0 );
381+ final int rightSize = ((r !=null )?r .size :0 );
382+
383+ int idx = Integer .MIN_VALUE ;
384+ if (p !=null && node .equals (p .left )) {
385+ // left
386+ idx = parentIndex - rightSize - 1 ;
387+ } else if (p !=null && node .equals (p .right )) {
388+ // right
389+ idx = leftSize + parentIndex + 1 ;
390+ } else {
391+ throw new RuntimeException ("I do not have a parent :-(" );
392+ }
393+
394+ if (idx == index )
395+ return node ;
396+
397+ if (index <= idx ) {
398+ return getNodeByIndex (l , idx , index );
399+ } else {
400+ return getNodeByIndex (r , idx , index );
401+ }
402+ }
403+
404+ private static <T > int getIndexByValue (Node <T > node , int parentIndex , T value ) {
390405 if (node == null )
391406 return Integer .MIN_VALUE ;
392407
@@ -410,11 +425,11 @@ private static <T> int getIndexByValue(T value, Node<T> node, int parentIndex) {
410425 if (value .equals (node .value ))
411426 return idx ;
412427
413- int i = getIndexByValue (value , l , idx );
428+ int i = getIndexByValue (l , idx , value );
414429 if (i >= 0 )
415430 return i ;
416431
417- i = getIndexByValue (value , r , idx );
432+ i = getIndexByValue (r , idx , value );
418433 return i ;
419434 }
420435
0 commit comments