@@ -23,7 +23,7 @@ export default class RedBlackTree<T> extends BinarySearchTree<T> {
23
23
private rotationLL ( node : RedBlackNode < T > ) {
24
24
const tmp = node . left ;
25
25
node . left = tmp . right ;
26
- if ( typeof tmp . right . key !== 'undefined' ) {
26
+ if ( tmp . right && tmp . right . key ) {
27
27
tmp . right . parent = node ;
28
28
}
29
29
tmp . parent = node . parent ;
@@ -54,7 +54,7 @@ export default class RedBlackTree<T> extends BinarySearchTree<T> {
54
54
private rotationRR ( node : RedBlackNode < T > ) {
55
55
const tmp = node . right ;
56
56
node . right = tmp . left ;
57
- if ( typeof tmp . left . key !== 'undefined' ) {
57
+ if ( tmp . left && tmp . left . key ) {
58
58
tmp . left . parent = node ;
59
59
}
60
60
tmp . parent = node . parent ;
@@ -101,101 +101,65 @@ export default class RedBlackTree<T> extends BinarySearchTree<T> {
101
101
}
102
102
103
103
private fixTreeProperties ( node : RedBlackNode < T > ) {
104
- let uncle : RedBlackNode < T > ;
105
- let grandParent : RedBlackNode < T > ;
106
104
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 ) {
123
115
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 ;
135
119
} 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 ;
139
125
}
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 ;
141
131
grandParent . color = Colors . RED ;
142
- this . leftRotate ( grandParent ) ;
132
+ node = parent ;
143
133
}
144
- }
145
- }
146
- this . root . color = Colors . BLACK ;
147
- }
148
134
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
174
136
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 ;
192
145
} 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 ;
194
159
}
195
160
}
196
- y . right = p ;
197
- p . parent = y ;
198
161
}
162
+ this . root . color = Colors . BLACK ;
199
163
}
200
164
201
165
getRoot ( ) {
0 commit comments