1 // RB tree utilities implementation -*- C++ -*-
3 // Copyright (C) 2003 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
32 * Copyright (c) 1996,1997
33 * Silicon Graphics Computer Systems, Inc.
35 * Permission to use, copy, modify, distribute and sell this software
36 * and its documentation for any purpose is hereby granted without fee,
37 * provided that the above copyright notice appear in all copies and
38 * that both that copyright notice and this permission notice appear
39 * in supporting documentation. Silicon Graphics makes no
40 * representations about the suitability of this software for any
41 * purpose. It is provided "as is" without express or implied warranty.
45 * Hewlett-Packard Company
47 * Permission to use, copy, modify, distribute and sell this software
48 * and its documentation for any purpose is hereby granted without fee,
49 * provided that the above copyright notice appear in all copies and
50 * that both that copyright notice and this permission notice appear
51 * in supporting documentation. Hewlett-Packard Company makes no
52 * representations about the suitability of this software for any
53 * purpose. It is provided "as is" without express or implied warranty.
58 #include <bits/stl_tree.h>
63 _Rb_tree_increment(_Rb_tree_node_base
* __x
)
65 if (__x
->_M_right
!= 0)
68 while (__x
->_M_left
!= 0)
73 _Rb_tree_node_base
* __y
= __x
->_M_parent
;
74 while (__x
== __y
->_M_right
)
79 if (__x
->_M_right
!= __y
)
86 _Rb_tree_decrement(_Rb_tree_node_base
* __x
)
88 if (__x
->_M_color
== _S_red
89 && __x
->_M_parent
->_M_parent
== __x
)
91 else if (__x
->_M_left
!= 0)
93 _Rb_tree_node_base
* __y
= __x
->_M_left
;
94 while (__y
->_M_right
!= 0)
100 _Rb_tree_node_base
* __y
= __x
->_M_parent
;
101 while (__x
== __y
->_M_left
)
104 __y
= __y
->_M_parent
;
112 _Rb_tree_rotate_left(_Rb_tree_node_base
* const __x
,
113 _Rb_tree_node_base
*& __root
)
115 _Rb_tree_node_base
* const __y
= __x
->_M_right
;
117 __x
->_M_right
= __y
->_M_left
;
118 if (__y
->_M_left
!=0)
119 __y
->_M_left
->_M_parent
= __x
;
120 __y
->_M_parent
= __x
->_M_parent
;
124 else if (__x
== __x
->_M_parent
->_M_left
)
125 __x
->_M_parent
->_M_left
= __y
;
127 __x
->_M_parent
->_M_right
= __y
;
129 __x
->_M_parent
= __y
;
133 _Rb_tree_rotate_right(_Rb_tree_node_base
* const __x
,
134 _Rb_tree_node_base
*& __root
)
136 _Rb_tree_node_base
* const __y
= __x
->_M_left
;
138 __x
->_M_left
= __y
->_M_right
;
139 if (__y
->_M_right
!= 0)
140 __y
->_M_right
->_M_parent
= __x
;
141 __y
->_M_parent
= __x
->_M_parent
;
145 else if (__x
== __x
->_M_parent
->_M_right
)
146 __x
->_M_parent
->_M_right
= __y
;
148 __x
->_M_parent
->_M_left
= __y
;
150 __x
->_M_parent
= __y
;
154 _Rb_tree_rebalance(_Rb_tree_node_base
* __x
, _Rb_tree_node_base
*& __root
)
156 __x
->_M_color
= _S_red
;
159 && __x
->_M_parent
->_M_color
== _S_red
)
161 _Rb_tree_node_base
* const __xpp
= __x
->_M_parent
->_M_parent
;
163 if (__x
->_M_parent
== __xpp
->_M_left
)
165 _Rb_tree_node_base
* const __y
= __xpp
->_M_right
;
166 if (__y
&& __y
->_M_color
== _S_red
)
168 __x
->_M_parent
->_M_color
= _S_black
;
169 __y
->_M_color
= _S_black
;
170 __xpp
->_M_color
= _S_red
;
175 if (__x
== __x
->_M_parent
->_M_right
)
177 __x
= __x
->_M_parent
;
178 _Rb_tree_rotate_left(__x
, __root
);
180 __x
->_M_parent
->_M_color
= _S_black
;
181 __xpp
->_M_color
= _S_red
;
182 _Rb_tree_rotate_right(__xpp
, __root
);
187 _Rb_tree_node_base
* const __y
= __xpp
->_M_left
;
188 if (__y
&& __y
->_M_color
== _S_red
)
190 __x
->_M_parent
->_M_color
= _S_black
;
191 __y
->_M_color
= _S_black
;
192 __xpp
->_M_color
= _S_red
;
197 if (__x
== __x
->_M_parent
->_M_left
)
199 __x
= __x
->_M_parent
;
200 _Rb_tree_rotate_right(__x
, __root
);
202 __x
->_M_parent
->_M_color
= _S_black
;
203 __xpp
->_M_color
= _S_red
;
204 _Rb_tree_rotate_left(__xpp
, __root
);
208 __root
->_M_color
= _S_black
;
212 _Rb_tree_rebalance_for_erase(_Rb_tree_node_base
* const __z
,
213 _Rb_tree_node_base
& __header
)
215 _Rb_tree_node_base
*& __root
= __header
._M_parent
;
216 _Rb_tree_node_base
*& __leftmost
= __header
._M_left
;
217 _Rb_tree_node_base
*& __rightmost
= __header
._M_right
;
218 _Rb_tree_node_base
* __y
= __z
;
219 _Rb_tree_node_base
* __x
= 0;
220 _Rb_tree_node_base
* __x_parent
= 0;
222 if (__y
->_M_left
== 0) // __z has at most one non-null child. y == z.
223 __x
= __y
->_M_right
; // __x might be null.
225 if (__y
->_M_right
== 0) // __z has exactly one non-null child. y == z.
226 __x
= __y
->_M_left
; // __x is not null.
229 // __z has two non-null children. Set __y to
230 __y
= __y
->_M_right
; // __z's successor. __x might be null.
231 while (__y
->_M_left
!= 0)
237 // relink y in place of z. y is z's successor
238 __z
->_M_left
->_M_parent
= __y
;
239 __y
->_M_left
= __z
->_M_left
;
240 if (__y
!= __z
->_M_right
)
242 __x_parent
= __y
->_M_parent
;
243 if (__x
) __x
->_M_parent
= __y
->_M_parent
;
244 __y
->_M_parent
->_M_left
= __x
; // __y must be a child of _M_left
245 __y
->_M_right
= __z
->_M_right
;
246 __z
->_M_right
->_M_parent
= __y
;
252 else if (__z
->_M_parent
->_M_left
== __z
)
253 __z
->_M_parent
->_M_left
= __y
;
255 __z
->_M_parent
->_M_right
= __y
;
256 __y
->_M_parent
= __z
->_M_parent
;
257 std::swap(__y
->_M_color
, __z
->_M_color
);
259 // __y now points to node to be actually deleted
263 __x_parent
= __y
->_M_parent
;
265 __x
->_M_parent
= __y
->_M_parent
;
269 if (__z
->_M_parent
->_M_left
== __z
)
270 __z
->_M_parent
->_M_left
= __x
;
272 __z
->_M_parent
->_M_right
= __x
;
273 if (__leftmost
== __z
)
274 if (__z
->_M_right
== 0) // __z->_M_left must be null also
275 __leftmost
= __z
->_M_parent
;
276 // makes __leftmost == _M_header if __z == __root
278 __leftmost
= _Rb_tree_node_base::_S_minimum(__x
);
279 if (__rightmost
== __z
)
280 if (__z
->_M_left
== 0) // __z->_M_right must be null also
281 __rightmost
= __z
->_M_parent
;
282 // makes __rightmost == _M_header if __z == __root
283 else // __x == __z->_M_left
284 __rightmost
= _Rb_tree_node_base::_S_maximum(__x
);
286 if (__y
->_M_color
!= _S_red
)
288 while (__x
!= __root
&& (__x
== 0 || __x
->_M_color
== _S_black
))
289 if (__x
== __x_parent
->_M_left
)
291 _Rb_tree_node_base
* __w
= __x_parent
->_M_right
;
292 if (__w
->_M_color
== _S_red
)
294 __w
->_M_color
= _S_black
;
295 __x_parent
->_M_color
= _S_red
;
296 _Rb_tree_rotate_left(__x_parent
, __root
);
297 __w
= __x_parent
->_M_right
;
299 if ((__w
->_M_left
== 0 ||
300 __w
->_M_left
->_M_color
== _S_black
) &&
301 (__w
->_M_right
== 0 ||
302 __w
->_M_right
->_M_color
== _S_black
))
304 __w
->_M_color
= _S_red
;
306 __x_parent
= __x_parent
->_M_parent
;
310 if (__w
->_M_right
== 0
311 || __w
->_M_right
->_M_color
== _S_black
)
313 __w
->_M_left
->_M_color
= _S_black
;
314 __w
->_M_color
= _S_red
;
315 _Rb_tree_rotate_right(__w
, __root
);
316 __w
= __x_parent
->_M_right
;
318 __w
->_M_color
= __x_parent
->_M_color
;
319 __x_parent
->_M_color
= _S_black
;
321 __w
->_M_right
->_M_color
= _S_black
;
322 _Rb_tree_rotate_left(__x_parent
, __root
);
328 // same as above, with _M_right <-> _M_left.
329 _Rb_tree_node_base
* __w
= __x_parent
->_M_left
;
330 if (__w
->_M_color
== _S_red
)
332 __w
->_M_color
= _S_black
;
333 __x_parent
->_M_color
= _S_red
;
334 _Rb_tree_rotate_right(__x_parent
, __root
);
335 __w
= __x_parent
->_M_left
;
337 if ((__w
->_M_right
== 0 ||
338 __w
->_M_right
->_M_color
== _S_black
) &&
339 (__w
->_M_left
== 0 ||
340 __w
->_M_left
->_M_color
== _S_black
))
342 __w
->_M_color
= _S_red
;
344 __x_parent
= __x_parent
->_M_parent
;
348 if (__w
->_M_left
== 0 || __w
->_M_left
->_M_color
== _S_black
)
350 __w
->_M_right
->_M_color
= _S_black
;
351 __w
->_M_color
= _S_red
;
352 _Rb_tree_rotate_left(__w
, __root
);
353 __w
= __x_parent
->_M_left
;
355 __w
->_M_color
= __x_parent
->_M_color
;
356 __x_parent
->_M_color
= _S_black
;
358 __w
->_M_left
->_M_color
= _S_black
;
359 _Rb_tree_rotate_right(__x_parent
, __root
);
363 if (__x
) __x
->_M_color
= _S_black
;
369 _Rb_tree_black_count(const _Rb_tree_node_base
* __node
,
370 const _Rb_tree_node_base
* __root
)
374 unsigned int __sum
= 0;
377 if (__node
->_M_color
== _S_black
)
379 if (__node
== __root
)
381 __node
= __node
->_M_parent
;