@@ -10,6 +10,7 @@ import delete_no_child from '../deletion/delete_no_child.js';
10
10
import search from '../search/search.js' ;
11
11
import inordertraversal from '../traversal/inordertraversal.js' ;
12
12
import rangetraversal from '../traversal/rangetraversal.js' ;
13
+ import replace_node from '../deletion/replace_node.js' ;
13
14
14
15
/**
15
16
* A RedBlackTree with key-only nodes.
@@ -110,13 +111,35 @@ export default class RedBlackTree {
110
111
delete_one_child ( pred ) ;
111
112
}
112
113
} else if ( node . right !== null ) {
113
- // Replace node's key with successor's key
114
- // NOTE: Since there is no left child, then there can only be one
115
- // right child by the red-black tree invariant.
114
+ /**
115
+ * Swap node with its successor.
116
+ *
117
+ * NOTE: Since pred is a leaf, there can only by one node in the
118
+ * right subtree, succ, which is necessarily red, hence
119
+ * node is black.
120
+ *
121
+ * The configuration:
122
+ *
123
+ * (A) (B) (C)
124
+ *
125
+ * p p p
126
+ * | | |
127
+ * node (BLACK) succ (BLACK) succ (BLACK)
128
+ * / \ / \ / \
129
+ * - succ (RED) -> - node (RED) -> - -
130
+ * / \ / \
131
+ * - - - -
132
+ *
133
+ * NOTE: We take a shortcut and go directly from (A) to (C)
134
+ */
116
135
const succ = node . right ;
117
- node . key = succ . key ;
118
- // Delete successor node
119
- delete_no_child ( succ ) ;
136
+ assert ( succ . _color === RED ) ;
137
+ succ . _color = BLACK ;
138
+ if ( node === this . root ) {
139
+ this . root = succ ;
140
+ } else {
141
+ replace_node ( node , succ ) ;
142
+ }
120
143
} else if ( node === this . root ) {
121
144
assert ( node . _color === BLACK ) ;
122
145
this . root = null ;
0 commit comments