@@ -106,27 +106,7 @@ def insert! node, target_parent = nil, direction = nil
106106 node . parent = target_parent
107107 node . red!
108108
109- while node . parent && node . parent . red? do
110- if node . parent . sibling && node . parent . sibling . red?
111- node . parent . black!
112- node . parent . sibling . black!
113- node . parent . parent . red!
114- node = node . parent . parent
115- else
116- opp_direction = node . opposite_position
117- if node . parent . position == opp_direction
118- rotate_sub_tree! node . parent , opp_direction
119- node = node [ opp_direction ]
120- end
121-
122- opp_direction = node . opposite_position
123- rotate_sub_tree! node . parent . parent , opp_direction
124- node . parent . black!
125- node . parent [ opp_direction ] . red!
126- end
127-
128- @root . black!
129- end
109+ rebalance_after_insertion! node
130110 end
131111
132112 node . validate! @root == node
@@ -153,71 +133,11 @@ def delete! node
153133 original_node = node
154134
155135 if node . children_are_valid?
156- is_root = is_root? node
157-
158- successor = node . left
159- successor = successor . left until successor . left . leaf?
160- node . swap_colour_with! successor
161- node . swap_position_with! successor
162- node . swap_position_with! LeafNode . new
163-
164- @root = successor if is_root
136+ delete_node_with_two_children! node
165137 elsif node . single_child_is_valid?
166- is_root = is_root? node
167-
168- valid_child = node . children . find ( &:valid? )
169- valid_child . black!
170- node . swap_position_with! valid_child
171- node . swap_position_with! LeafNode . new
172-
173- @root = valid_child if is_root
138+ delete_node_with_one_child! node
174139 elsif node . children_are_leaves?
175- if is_root? node
176- @root = nil
177- elsif node . red?
178- node . swap_position_with! LeafNode . new
179- else
180- loop do
181- if node . sibling && node . sibling . valid? && node . sibling . red?
182- node . parent . red!
183- node . sibling . black!
184- rotate_sub_tree! node . parent , node . position
185- end
186-
187- if node . close_nephew && node . close_nephew . valid? && node . close_nephew . red?
188- node . sibling . red! unless node . sibling . leaf?
189- node . close_nephew . black!
190- rotate_sub_tree! node . sibling , node . opposite_position
191- end
192-
193- if node . distant_nephew && node . distant_nephew . valid? && node . distant_nephew . red?
194- case node . parent . colour
195- when Node ::RED then node . sibling . red!
196- when Node ::BLACK then node . sibling . black!
197- end
198- node . parent . black!
199- node . distant_nephew . black!
200- rotate_sub_tree! node . parent , node . position
201-
202- break
203- end
204-
205- if node . parent && node . parent . red?
206- node . sibling . red! unless node . sibling . leaf?
207- node . parent . black!
208-
209- break
210- end
211-
212- if node . sibling && !node . sibling . leaf?
213- node . sibling . red!
214- end
215-
216- break unless node = node . parent
217- end
218-
219- original_node . swap_position_with! LeafNode . new
220- end
140+ delete_leaf_node! node , original_node
221141 end
222142
223143 original_node . tree = nil
@@ -270,7 +190,7 @@ def select &block
270190 #
271191 # @return [true, false]
272192 def include? data
273- !! search ( data )
193+ !search ( data ) . nil?
274194 end
275195
276196 # Traverses the tree in pre-order and yields each node.
@@ -333,6 +253,29 @@ def traverse_level_order &block
333253
334254 private
335255
256+ def is_root? node
257+ node && @root && node . object_id == @root . object_id
258+ end
259+
260+ def increment_size!
261+ @size += 1
262+ end
263+
264+ def decrement_size!
265+ @size -= 1
266+ end
267+
268+ def update_left_most_node!
269+ unless @root
270+ @left_most_node = nil
271+ return
272+ end
273+
274+ current = @root
275+ current = current . left until current . left . leaf?
276+ @left_most_node = current
277+ end
278+
336279 # Rotates a (sub-)tree starting from the given node in the given direction.
337280 #
338281 # @param node [RedBlackTree::Node] the root node of the sub-tree
@@ -359,12 +302,111 @@ def rotate_sub_tree! node, direction
359302 opp_direction_child
360303 end
361304
305+ def rebalance_after_insertion! node
306+ while node . parent && node . parent . red? do
307+ if node . parent . sibling && node . parent . sibling . red?
308+ node . parent . black!
309+ node . parent . sibling . black!
310+ node . parent . parent . red!
311+ node = node . parent . parent
312+ else
313+ opp_direction = node . opposite_position
314+ if node . parent . position == opp_direction
315+ rotate_sub_tree! node . parent , opp_direction
316+ node = node [ opp_direction ]
317+ end
318+
319+ opp_direction = node . opposite_position
320+ rotate_sub_tree! node . parent . parent , opp_direction
321+ node . parent . black!
322+ node . parent [ opp_direction ] . red!
323+ end
324+
325+ @root . black!
326+ end
327+ end
328+
329+ def delete_node_with_two_children! node
330+ is_root = is_root? node
331+
332+ successor = node . left
333+ successor = successor . right until successor . right . leaf?
334+ node . swap_colour_with! successor
335+ node . swap_position_with! successor
336+ node . swap_position_with! LeafNode . new
337+
338+ @root = successor if is_root
339+ end
340+
341+ def delete_node_with_one_child! node
342+ is_root = is_root? node
343+
344+ valid_child = node . children . find ( &:valid? )
345+ valid_child . black!
346+ node . swap_position_with! valid_child
347+ node . swap_position_with! LeafNode . new
348+
349+ @root = valid_child if is_root
350+ end
351+
352+ def delete_leaf_node! node , original_node
353+ if is_root? node
354+ @root = nil
355+ elsif node . red?
356+ node . swap_position_with! LeafNode . new
357+ else
358+ rebalance_after_deletion! node
359+ original_node . swap_position_with! LeafNode . new
360+ end
361+ end
362+
363+ def rebalance_after_deletion! node
364+ loop do
365+ if node . sibling && node . sibling . valid? && node . sibling . red?
366+ node . parent . red!
367+ node . sibling . black!
368+ rotate_sub_tree! node . parent , node . position
369+ end
370+
371+ if node . close_nephew && node . close_nephew . valid? && node . close_nephew . red?
372+ node . sibling . red! unless node . sibling . leaf?
373+ node . close_nephew . black!
374+ rotate_sub_tree! node . sibling , node . opposite_position
375+ end
376+
377+ if node . distant_nephew && node . distant_nephew . valid? && node . distant_nephew . red?
378+ case node . parent . colour
379+ when Node ::RED then node . sibling . red!
380+ when Node ::BLACK then node . sibling . black!
381+ end
382+ node . parent . black!
383+ node . distant_nephew . black!
384+ rotate_sub_tree! node . parent , node . position
385+
386+ break
387+ end
388+
389+ if node . parent && node . parent . red?
390+ node . sibling . red! unless node . sibling . leaf?
391+ node . parent . black!
392+
393+ break
394+ end
395+
396+ if node . sibling && !node . sibling . leaf?
397+ node . sibling . red!
398+ end
399+
400+ break unless node = node . parent
401+ end
402+ end
403+
362404 def _search_by_data data , node
363405 return if node . nil? || node . leaf?
364406 return node if data == node . data
365407
366- mock_node = node . class . new data
367- if mock_node >= node
408+ comparison = data <=> node . data
409+ if comparison && comparison >= 0
368410 _search_by_data data , node . right
369411 else
370412 _search_by_data data , node . left
@@ -388,27 +430,4 @@ def _select_by_block block, node
388430 end
389431 end
390432 end
391-
392- def is_root? node
393- node && @root && node . object_id == @root . object_id
394- end
395-
396- def increment_size!
397- @size += 1
398- end
399-
400- def decrement_size!
401- @size -= 1
402- end
403-
404- def update_left_most_node!
405- unless @root
406- @left_most_node = nil
407- return
408- end
409-
410- current = @root
411- current = current . left until current . left . leaf?
412- @left_most_node = current
413- end
414433end
0 commit comments