3232 * @module data-structures/size-balanced-tree
3333 */
3434
35- function CreateSBTreeClass ( Node , Nil ) {
36- function updateChild ( node , newChild ) {
37- var parent = node . parent ;
38- if ( parent !== Nil ) {
39- if ( parent . right === node ) {
40- parent . right = newChild ;
41- } else {
42- parent . left = newChild ;
43- }
44- parent . updateSize ( ) ;
45- }
46- if ( newChild !== Nil ) {
47- newChild . parent = parent ;
48- }
49- }
50-
35+ function CreateSBTreeClass ( Node , Nil , updateChild ) {
5136 function LeftRotate ( node , childNode ) {
5237 /*
5338 Before rotate:
@@ -69,9 +54,8 @@ function CreateSBTreeClass (Node, Nil) {
6954 node . right . parent = node ;
7055 }
7156 childNode . left = node ;
72- updateChild ( node , childNode ) ; //Access node.parent
73- node . parent = childNode ;
74- node . updateSize ( ) ;
57+ // setting childNode's parent to node's parent
58+ updateChild ( node , childNode ) ;
7559 return childNode ;
7660 }
7761
@@ -96,9 +80,8 @@ function CreateSBTreeClass (Node, Nil) {
9680 node . left . parent = node ;
9781 }
9882 childNode . right = node ;
99- updateChild ( node , childNode ) ; //Access node.parent
100- node . parent = childNode ;
101- node . updateSize ( ) ;
83+ // setting childNode's parent to node's parent
84+ updateChild ( node , childNode ) ;
10285 return childNode ;
10386 }
10487
@@ -122,7 +105,6 @@ function CreateSBTreeClass (Node, Nil) {
122105 node = LeftRotate ( node , node . right ) ;
123106 }
124107 }
125- node . updateSize ( ) ;
126108 if ( node === savedNode ) {
127109 return node ;
128110 }
@@ -146,20 +128,6 @@ function CreateSBTreeClass (Node, Nil) {
146128 return node ;
147129 }
148130
149- function findRightMost ( node ) {
150- while ( node . right !== Nil ) {
151- node = node . right ;
152- }
153- return node ;
154- }
155-
156- function findLeftMost ( node ) {
157- while ( node . left !== Nil ) {
158- node = node . left ;
159- }
160- return node ;
161- }
162-
163131 function findNodeAtPos ( node , pos ) {
164132 while ( pos !== node . left . size ) {
165133 if ( pos < node . left . size ) {
@@ -183,7 +151,6 @@ function CreateSBTreeClass (Node, Nil) {
183151
184152 SBTree . prototype = {
185153 _root : Nil ,
186- updateChild : updateChild ,
187154 get size ( ) {
188155 return this . _root . size ;
189156 } ,
@@ -208,26 +175,8 @@ function CreateSBTreeClass (Node, Nil) {
208175 } ,
209176 } ;
210177
211- /**
212- * Push a value to the end of tree.
213- * Complexity: O(log N).
214- *
215- * @public
216- * @method
217- * @param {Object } value Value.
218- */
219- SBTree . prototype . push = function ( value ) {
220- var node = findRightMost ( this . _root ) ;
221- var newNode = new Node ( value , node , Nil , Nil , 1 ) ;
222- if ( node !== Nil ) {
223- node . right = newNode ;
224- }
225- this . _root = maintainSizeBalancedTree ( newNode ) ;
226- return newNode ;
227- } ;
228-
229178 SBTree . prototype . get = function ( pos ) {
230- if ( pos >= this . _root . size ) {
179+ if ( pos >= this . size ) {
231180 return Nil ;
232181 }
233182 return findNodeAtPos ( this . _root , pos ) ;
@@ -245,83 +194,97 @@ function CreateSBTreeClass (Node, Nil) {
245194 return index ;
246195 } ;
247196
248- SBTree . prototype . insert = function ( pos , value ) {
249- if ( pos >= this . _root . size ) {
250- return this . push ( value ) ;
197+ SBTree . prototype . shiftDown = function ( node ) {
198+ var direction = 0 ;
199+ while ( true ) {
200+ if ( node . left !== Nil && node . right !== Nil ) {
201+ switch ( direction ) {
202+ case 0 :
203+ RightRotate ( node , node . left ) ;
204+ break ;
205+ case 1 :
206+ LeftRotate ( node , node . right ) ;
207+ break ;
208+ }
209+ direction = 1 - direction ;
210+ } else if ( node . left !== Nil ) {
211+ RightRotate ( node , node . left ) ;
212+ } else if ( node . right !== Nil ) {
213+ LeftRotate ( node , node . right ) ;
214+ } else {
215+ break ; // The node could be able to removed
216+ }
251217 }
252- var node = findNodeAtPos ( this . _root , pos ) ;
253- var newNode ;
254- if ( node . left === Nil ) {
255- newNode = new Node ( value , node , Nil , Nil , 1 ) ;
256- node . left = newNode ;
218+ } ;
219+
220+ SBTree . prototype . insertLeafNode = function ( node ) {
221+ var parent = node . parent ;
222+ while ( parent !== Nil ) {
223+ parent . size = parent . size + 1 ;
224+ parent = parent . parent ;
225+ }
226+ } ;
227+
228+ SBTree . prototype . removeLeafNode = function ( node ) {
229+ var parent = node . parent ;
230+ while ( parent !== Nil ) {
231+ parent . size = parent . size - 1 ;
232+ parent = parent . parent ;
233+ }
234+ } ;
235+
236+ SBTree . prototype . insert = function ( pos , value ) {
237+ var node = Nil ;
238+ var newNode = new Node ( value , Nil , Nil , Nil , 1 ) ;
239+ if ( pos === this . size ) {
240+ if ( pos > 0 ) {
241+ node = findNodeAtPos ( this . _root , pos - 1 ) ;
242+ node . right = newNode ;
243+ }
257244 } else {
258- node = findRightMost ( node . left ) ;
259- newNode = new Node ( value , node , Nil , Nil , 1 ) ;
260- node . right = newNode ;
245+ node = findNodeAtPos ( this . _root , pos ) ;
246+ if ( node . left !== Nil ) {
247+ this . shiftDown ( node ) ;
248+ }
249+ node . left = newNode ;
261250 }
251+ newNode . parent = node ;
252+ this . insertLeafNode ( newNode ) ;
262253 this . _root = maintainSizeBalancedTree ( newNode ) ;
263254 return newNode ;
264255 } ;
265256
257+ /**
258+ * Push a value to the end of tree.
259+ * Complexity: O(log N).
260+ *
261+ * @public
262+ * @method
263+ * @param {Object } value Value.
264+ */
265+ SBTree . prototype . push = function ( value ) {
266+ this . insert ( this . size , value ) ;
267+ } ;
268+
269+ SBTree . prototype . removeNode = function ( node ) {
270+ this . shiftDown ( node ) ;
271+ var maintainNode = node . parent ;
272+ if ( maintainNode . left === node ) {
273+ maintainNode . left = Nil ;
274+ } else if ( maintainNode . right === node ) {
275+ maintainNode . right = Nil ;
276+ }
277+ this . removeLeafNode ( node ) ;
278+ this . _root = maintainSizeBalancedTree ( maintainNode ) ;
279+ return node ;
280+ } ;
281+
266282 SBTree . prototype . remove = function ( pos ) {
267283 if ( pos >= this . _root . size ) {
268284 return Nil ; // There is no element to remove
269285 }
270286 var node = findNodeAtPos ( this . _root , pos ) ;
271- var maintainNode ;
272-
273- /*
274- Before remove:
275- P (node's parent, be notices,
276- | N either be left child or right child of P)
277- |
278- N(node)
279- / \
280- L R
281- \
282- \
283- LRM(Left-Rightmost)
284- \
285- Nil
286- After remove node N:
287- P(node's parent)
288- /
289- L
290- \
291- \
292- LRM(Left-Rightmost)
293- \
294- R
295-
296- N(node) is wild node that was removed
297-
298- */
299- if ( node . left !== Nil ) {
300- var LRM = findRightMost ( node . left ) ;
301- updateChild ( node , node . left ) ;
302- LRM . right = node . right ;
303- if ( LRM . right === Nil ) {
304- maintainNode = LRM ;
305- } else {
306- LRM . right . parent = LRM ;
307- maintainNode = LRM . right ;
308- }
309- } else if ( node . right !== Nil ) {
310- var RLM = findLeftMost ( node . right ) ;
311- updateChild ( node , node . right ) ;
312- RLM . left = node . left ;
313- if ( RLM . left === Nil ) {
314- maintainNode = RLM ;
315- } else {
316- RLM . left . parent = RLM ;
317- maintainNode = RLM . left ;
318- }
319- } else {
320- updateChild ( node , Nil ) ;
321- maintainNode = node . parent ;
322- }
323- this . _root = maintainSizeBalancedTree ( maintainNode ) ;
324- return node ;
287+ return this . removeNode ( node ) ;
325288 } ;
326289
327290 return SBTree ;
@@ -349,6 +312,14 @@ function CreateSBTreeClass (Node, Nil) {
349312 this . height = 0 ;
350313 } ;
351314
315+ var createNil = function ( Node , value ) {
316+ var Nil = new Node ( value , null , null , null , 0 ) ;
317+ Nil . parent = Nil ;
318+ Nil . left = Nil ;
319+ Nil . right = Nil ;
320+ return Nil ;
321+ } ;
322+
352323 /**
353324 * Update node's size.
354325 *
@@ -360,12 +331,22 @@ function CreateSBTreeClass (Node, Nil) {
360331 this . height = Math . max ( this . left . height , this . right . height ) + 1 ;
361332 } ;
362333
363- var createNil = function ( Node , value ) {
364- var Nil = new Node ( value , null , null , null , 0 ) ;
365- Nil . parent = Nil ;
366- Nil . left = Nil ;
367- Nil . right = Nil ;
368- return Nil ;
334+ // node, childNode must not be Nil,
335+ // if the childNode turn out to be the root, the parent should be Nil
336+ var updateChild = function ( node , childNode ) {
337+ var parent = node . parent ;
338+ node . parent = childNode ;
339+ childNode . parent = parent ;
340+
341+ node . updateSize ( ) ;
342+ childNode . updateSize ( ) ;
343+ if ( parent . right === node ) {
344+ parent . right = childNode ;
345+ parent . updateSize ( ) ;
346+ } else if ( parent . left === node ) {
347+ parent . left = childNode ;
348+ parent . updateSize ( ) ;
349+ } // otherwise parent is Nil
369350 } ;
370351
371352 var Node = function ( ) {
@@ -379,11 +360,11 @@ function CreateSBTreeClass (Node, Nil) {
379360 exports . NodeConstructor = NodeConstructor ;
380361 exports . createNil = createNil ;
381362 exports . updateSize = updateSize ;
363+ exports . updateChild = updateChild ;
382364 exports . CreateSBTreeClass = CreateSBTreeClass ;
383365
384366 exports . Node = Node ;
385367 exports . Nil = Nil ;
386- exports . SBTree = CreateSBTreeClass ( Node , Nil ) ;
387- exports . updateChild = exports . SBTree . prototype . updateChild ;
368+ exports . SBTree = CreateSBTreeClass ( Node , Nil , updateChild ) ;
388369
389370} ) ( typeof module === 'undefined' ? window : module . exports ) ;
0 commit comments