1 // RB tree utilities implementation -*- C++ -*-
3 // Copyright (C) 2003, 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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>
60 _GLIBCXX_BEGIN_NAMESPACE(std
)
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
)
85 const _Rb_tree_node_base
*
86 _Rb_tree_increment(const _Rb_tree_node_base
* __x
)
88 return _Rb_tree_increment(const_cast<_Rb_tree_node_base
*>(__x
));
92 _Rb_tree_decrement(_Rb_tree_node_base
* __x
)
94 if (__x
->_M_color
== _S_red
95 && __x
->_M_parent
->_M_parent
== __x
)
97 else if (__x
->_M_left
!= 0)
99 _Rb_tree_node_base
* __y
= __x
->_M_left
;
100 while (__y
->_M_right
!= 0)
106 _Rb_tree_node_base
* __y
= __x
->_M_parent
;
107 while (__x
== __y
->_M_left
)
110 __y
= __y
->_M_parent
;
117 const _Rb_tree_node_base
*
118 _Rb_tree_decrement(const _Rb_tree_node_base
* __x
)
120 return _Rb_tree_decrement(const_cast<_Rb_tree_node_base
*>(__x
));
124 _Rb_tree_rotate_left(_Rb_tree_node_base
* const __x
,
125 _Rb_tree_node_base
*& __root
)
127 _Rb_tree_node_base
* const __y
= __x
->_M_right
;
129 __x
->_M_right
= __y
->_M_left
;
130 if (__y
->_M_left
!=0)
131 __y
->_M_left
->_M_parent
= __x
;
132 __y
->_M_parent
= __x
->_M_parent
;
136 else if (__x
== __x
->_M_parent
->_M_left
)
137 __x
->_M_parent
->_M_left
= __y
;
139 __x
->_M_parent
->_M_right
= __y
;
141 __x
->_M_parent
= __y
;
145 _Rb_tree_rotate_right(_Rb_tree_node_base
* const __x
,
146 _Rb_tree_node_base
*& __root
)
148 _Rb_tree_node_base
* const __y
= __x
->_M_left
;
150 __x
->_M_left
= __y
->_M_right
;
151 if (__y
->_M_right
!= 0)
152 __y
->_M_right
->_M_parent
= __x
;
153 __y
->_M_parent
= __x
->_M_parent
;
157 else if (__x
== __x
->_M_parent
->_M_right
)
158 __x
->_M_parent
->_M_right
= __y
;
160 __x
->_M_parent
->_M_left
= __y
;
162 __x
->_M_parent
= __y
;
166 _Rb_tree_insert_and_rebalance(const bool __insert_left
,
167 _Rb_tree_node_base
* __x
,
168 _Rb_tree_node_base
* __p
,
169 _Rb_tree_node_base
& __header
)
171 _Rb_tree_node_base
*& __root
= __header
._M_parent
;
173 // Initialize fields in new node to insert.
174 __x
->_M_parent
= __p
;
177 __x
->_M_color
= _S_red
;
180 // Make new node child of parent and maintain root, leftmost and
182 // N.B. First node is always inserted left.
185 __p
->_M_left
= __x
; // also makes leftmost = __x when __p == &__header
187 if (__p
== &__header
)
189 __header
._M_parent
= __x
;
190 __header
._M_right
= __x
;
192 else if (__p
== __header
._M_left
)
193 __header
._M_left
= __x
; // maintain leftmost pointing to min node
199 if (__p
== __header
._M_right
)
200 __header
._M_right
= __x
; // maintain rightmost pointing to max node
204 && __x
->_M_parent
->_M_color
== _S_red
)
206 _Rb_tree_node_base
* const __xpp
= __x
->_M_parent
->_M_parent
;
208 if (__x
->_M_parent
== __xpp
->_M_left
)
210 _Rb_tree_node_base
* const __y
= __xpp
->_M_right
;
211 if (__y
&& __y
->_M_color
== _S_red
)
213 __x
->_M_parent
->_M_color
= _S_black
;
214 __y
->_M_color
= _S_black
;
215 __xpp
->_M_color
= _S_red
;
220 if (__x
== __x
->_M_parent
->_M_right
)
222 __x
= __x
->_M_parent
;
223 _Rb_tree_rotate_left(__x
, __root
);
225 __x
->_M_parent
->_M_color
= _S_black
;
226 __xpp
->_M_color
= _S_red
;
227 _Rb_tree_rotate_right(__xpp
, __root
);
232 _Rb_tree_node_base
* const __y
= __xpp
->_M_left
;
233 if (__y
&& __y
->_M_color
== _S_red
)
235 __x
->_M_parent
->_M_color
= _S_black
;
236 __y
->_M_color
= _S_black
;
237 __xpp
->_M_color
= _S_red
;
242 if (__x
== __x
->_M_parent
->_M_left
)
244 __x
= __x
->_M_parent
;
245 _Rb_tree_rotate_right(__x
, __root
);
247 __x
->_M_parent
->_M_color
= _S_black
;
248 __xpp
->_M_color
= _S_red
;
249 _Rb_tree_rotate_left(__xpp
, __root
);
253 __root
->_M_color
= _S_black
;
257 _Rb_tree_rebalance_for_erase(_Rb_tree_node_base
* const __z
,
258 _Rb_tree_node_base
& __header
)
260 _Rb_tree_node_base
*& __root
= __header
._M_parent
;
261 _Rb_tree_node_base
*& __leftmost
= __header
._M_left
;
262 _Rb_tree_node_base
*& __rightmost
= __header
._M_right
;
263 _Rb_tree_node_base
* __y
= __z
;
264 _Rb_tree_node_base
* __x
= 0;
265 _Rb_tree_node_base
* __x_parent
= 0;
267 if (__y
->_M_left
== 0) // __z has at most one non-null child. y == z.
268 __x
= __y
->_M_right
; // __x might be null.
270 if (__y
->_M_right
== 0) // __z has exactly one non-null child. y == z.
271 __x
= __y
->_M_left
; // __x is not null.
274 // __z has two non-null children. Set __y to
275 __y
= __y
->_M_right
; // __z's successor. __x might be null.
276 while (__y
->_M_left
!= 0)
282 // relink y in place of z. y is z's successor
283 __z
->_M_left
->_M_parent
= __y
;
284 __y
->_M_left
= __z
->_M_left
;
285 if (__y
!= __z
->_M_right
)
287 __x_parent
= __y
->_M_parent
;
288 if (__x
) __x
->_M_parent
= __y
->_M_parent
;
289 __y
->_M_parent
->_M_left
= __x
; // __y must be a child of _M_left
290 __y
->_M_right
= __z
->_M_right
;
291 __z
->_M_right
->_M_parent
= __y
;
297 else if (__z
->_M_parent
->_M_left
== __z
)
298 __z
->_M_parent
->_M_left
= __y
;
300 __z
->_M_parent
->_M_right
= __y
;
301 __y
->_M_parent
= __z
->_M_parent
;
302 std::swap(__y
->_M_color
, __z
->_M_color
);
304 // __y now points to node to be actually deleted
308 __x_parent
= __y
->_M_parent
;
310 __x
->_M_parent
= __y
->_M_parent
;
314 if (__z
->_M_parent
->_M_left
== __z
)
315 __z
->_M_parent
->_M_left
= __x
;
317 __z
->_M_parent
->_M_right
= __x
;
318 if (__leftmost
== __z
)
320 if (__z
->_M_right
== 0) // __z->_M_left must be null also
321 __leftmost
= __z
->_M_parent
;
322 // makes __leftmost == _M_header if __z == __root
324 __leftmost
= _Rb_tree_node_base::_S_minimum(__x
);
326 if (__rightmost
== __z
)
328 if (__z
->_M_left
== 0) // __z->_M_right must be null also
329 __rightmost
= __z
->_M_parent
;
330 // makes __rightmost == _M_header if __z == __root
331 else // __x == __z->_M_left
332 __rightmost
= _Rb_tree_node_base::_S_maximum(__x
);
335 if (__y
->_M_color
!= _S_red
)
337 while (__x
!= __root
&& (__x
== 0 || __x
->_M_color
== _S_black
))
338 if (__x
== __x_parent
->_M_left
)
340 _Rb_tree_node_base
* __w
= __x_parent
->_M_right
;
341 if (__w
->_M_color
== _S_red
)
343 __w
->_M_color
= _S_black
;
344 __x_parent
->_M_color
= _S_red
;
345 _Rb_tree_rotate_left(__x_parent
, __root
);
346 __w
= __x_parent
->_M_right
;
348 if ((__w
->_M_left
== 0 ||
349 __w
->_M_left
->_M_color
== _S_black
) &&
350 (__w
->_M_right
== 0 ||
351 __w
->_M_right
->_M_color
== _S_black
))
353 __w
->_M_color
= _S_red
;
355 __x_parent
= __x_parent
->_M_parent
;
359 if (__w
->_M_right
== 0
360 || __w
->_M_right
->_M_color
== _S_black
)
362 __w
->_M_left
->_M_color
= _S_black
;
363 __w
->_M_color
= _S_red
;
364 _Rb_tree_rotate_right(__w
, __root
);
365 __w
= __x_parent
->_M_right
;
367 __w
->_M_color
= __x_parent
->_M_color
;
368 __x_parent
->_M_color
= _S_black
;
370 __w
->_M_right
->_M_color
= _S_black
;
371 _Rb_tree_rotate_left(__x_parent
, __root
);
377 // same as above, with _M_right <-> _M_left.
378 _Rb_tree_node_base
* __w
= __x_parent
->_M_left
;
379 if (__w
->_M_color
== _S_red
)
381 __w
->_M_color
= _S_black
;
382 __x_parent
->_M_color
= _S_red
;
383 _Rb_tree_rotate_right(__x_parent
, __root
);
384 __w
= __x_parent
->_M_left
;
386 if ((__w
->_M_right
== 0 ||
387 __w
->_M_right
->_M_color
== _S_black
) &&
388 (__w
->_M_left
== 0 ||
389 __w
->_M_left
->_M_color
== _S_black
))
391 __w
->_M_color
= _S_red
;
393 __x_parent
= __x_parent
->_M_parent
;
397 if (__w
->_M_left
== 0 || __w
->_M_left
->_M_color
== _S_black
)
399 __w
->_M_right
->_M_color
= _S_black
;
400 __w
->_M_color
= _S_red
;
401 _Rb_tree_rotate_left(__w
, __root
);
402 __w
= __x_parent
->_M_left
;
404 __w
->_M_color
= __x_parent
->_M_color
;
405 __x_parent
->_M_color
= _S_black
;
407 __w
->_M_left
->_M_color
= _S_black
;
408 _Rb_tree_rotate_right(__x_parent
, __root
);
412 if (__x
) __x
->_M_color
= _S_black
;
418 _Rb_tree_black_count(const _Rb_tree_node_base
* __node
,
419 const _Rb_tree_node_base
* __root
)
423 unsigned int __sum
= 0;
426 if (__node
->_M_color
== _S_black
)
428 if (__node
== __root
)
430 __node
= __node
->_M_parent
;
436 _GLIBCXX_END_NAMESPACE