@@ -23,7 +23,7 @@ export default class RedBlackTree<T> extends BinarySearchTree<T> {
2323 private rotationLL ( node : RedBlackNode < T > ) {
2424 const tmp = node . left ;
2525 node . left = tmp . right ;
26- if ( typeof tmp . right . key !== 'undefined' ) {
26+ if ( tmp . right && tmp . right . key ) {
2727 tmp . right . parent = node ;
2828 }
2929 tmp . parent = node . parent ;
@@ -54,7 +54,7 @@ export default class RedBlackTree<T> extends BinarySearchTree<T> {
5454 private rotationRR ( node : RedBlackNode < T > ) {
5555 const tmp = node . right ;
5656 node . right = tmp . left ;
57- if ( typeof tmp . left . key !== 'undefined' ) {
57+ if ( tmp . left && tmp . left . key ) {
5858 tmp . left . parent = node ;
5959 }
6060 tmp . parent = node . parent ;
@@ -101,101 +101,65 @@ export default class RedBlackTree<T> extends BinarySearchTree<T> {
101101 }
102102
103103 private fixTreeProperties ( node : RedBlackNode < T > ) {
104- let uncle : RedBlackNode < T > ;
105- let grandParent : RedBlackNode < T > ;
106104 while ( node && node . parent && node . parent . color === Colors . RED && node . color !== Colors . BLACK ) {
107- grandParent = node . parent . parent ;
108- if ( grandParent && grandParent . left === node . parent ) {
109- if ( grandParent . right != null ) {
110- uncle = grandParent . right ;
111- if ( uncle . color === Colors . RED ) {
112- node . parent . color = Colors . BLACK ;
113- uncle . color = Colors . BLACK ;
114- grandParent . color = Colors . RED ;
115- node = grandParent ;
116- }
117- } else {
118- if ( node . parent . right === node ) {
119- node = node . parent ;
120- this . leftRotate ( node ) ;
121- }
122- node . parent . color = Colors . BLACK ;
105+ let parent = node . parent ;
106+ const grandParent = parent . parent ;
107+
108+ // case A
109+ if ( grandParent && grandParent . left === parent ) {
110+
111+ const uncle = grandParent . right ;
112+
113+ // case 1: uncle of node is also red - only recoloring
114+ if ( uncle && uncle . color === Colors . RED ) {
123115 grandParent . color = Colors . RED ;
124- this . rightRotate ( grandParent ) ;
125- }
126- } else {
127- if ( grandParent . left != null ) {
128- uncle = grandParent . left ;
129- if ( uncle . color === Colors . RED ) {
130- node . parent . color = Colors . BLACK ;
131- uncle . color = Colors . BLACK ;
132- grandParent . color = Colors . RED ;
133- node = grandParent ;
134- }
116+ parent . color = Colors . BLACK ;
117+ uncle . color = Colors . BLACK ;
118+ node = grandParent ;
135119 } else {
136- if ( node . parent . left === node ) {
137- node = node . parent ;
138- this . rightRotate ( node ) ;
120+ // case 2: node is right child - left rotate
121+ if ( node === parent . right ) {
122+ this . rotationRR ( parent ) ;
123+ node = parent ;
124+ parent = node . parent ;
139125 }
140- node . parent . color = Colors . BLACK ;
126+
127+ // case 3: node is left child - right rotate
128+ this . rotationLL ( grandParent ) ;
129+ // swap color
130+ parent . color = Colors . BLACK ;
141131 grandParent . color = Colors . RED ;
142- this . leftRotate ( grandParent ) ;
132+ node = parent ;
143133 }
144- }
145- }
146- this . root . color = Colors . BLACK ;
147- }
148134
149- leftRotate ( p : RedBlackNode < T > ) {
150- if ( p . right != null ) {
151- const y = p . right ;
152- if ( y . left != null ) {
153- p . right = y . left ;
154- y . left . parent = p ;
155- } else {
156- p . right = null ;
157- }
158- if ( p . parent != null ) {
159- y . parent = p . parent ;
160- }
161- if ( p . parent == null ) {
162- this . root = y ;
163- } else {
164- if ( p === p . parent . left ) {
165- p . parent . left = y ;
166- } else {
167- p . parent . right = y ;
168- }
169- }
170- y . left = p ;
171- p . parent = y ;
172- }
173- }
135+ } else { // case B: parent is right child of grand parent
174136
175- rightRotate ( p : RedBlackNode < T > ) {
176- if ( p . left != null ) {
177- const y = p . left ;
178- if ( y . right != null ) {
179- p . left = y . right ;
180- y . right . parent = p ;
181- } else {
182- p . left = null ;
183- }
184- if ( p . parent != null ) {
185- y . parent = p . parent ;
186- }
187- if ( p . parent == null ) {
188- this . root = y ;
189- } else {
190- if ( p === p . parent . left ) {
191- p . parent . left = y ;
137+ const uncle = grandParent . left ;
138+
139+ // case 1: uncle is read - only recoloring
140+ if ( uncle && uncle . color === Colors . RED ) {
141+ grandParent . color = Colors . RED ;
142+ parent . color = Colors . BLACK ;
143+ uncle . color = Colors . BLACK ;
144+ node = grandParent ;
192145 } else {
193- p . parent . right = y ;
146+ // case 2: node is left child - left rotate
147+ if ( node === parent . left ) {
148+ this . rotationLL ( parent ) ;
149+ node = parent ;
150+ parent = node . parent ;
151+ }
152+
153+ // case 3: node is right child - left rotate
154+ this . rotationRR ( grandParent ) ;
155+ // swap color
156+ parent . color = Colors . BLACK ;
157+ grandParent . color = Colors . RED ;
158+ node = parent ;
194159 }
195160 }
196- y . right = p ;
197- p . parent = y ;
198161 }
162+ this . root . color = Colors . BLACK ;
199163 }
200164
201165 getRoot ( ) {
0 commit comments