1 // RB tree utilities implementation -*- C++ -*-
3 // Copyright (C) 2003, 2005, 2009 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 3, 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 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
27 * Copyright (c) 1996,1997
28 * Silicon Graphics Computer Systems, Inc.
30 * Permission to use, copy, modify, distribute and sell this software
31 * and its documentation for any purpose is hereby granted without fee,
32 * provided that the above copyright notice appear in all copies and
33 * that both that copyright notice and this permission notice appear
34 * in supporting documentation. Silicon Graphics makes no
35 * representations about the suitability of this software for any
36 * purpose. It is provided "as is" without express or implied warranty.
40 * Hewlett-Packard Company
42 * Permission to use, copy, modify, distribute and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appear in all copies and
45 * that both that copyright notice and this permission notice appear
46 * in supporting documentation. Hewlett-Packard Company makes no
47 * representations about the suitability of this software for any
48 * purpose. It is provided "as is" without express or implied warranty.
53 #include <bits/stl_tree.h>
55 _GLIBCXX_BEGIN_NAMESPACE(std
)
58 _Rb_tree_increment(_Rb_tree_node_base
* __x
)
60 if (__x
->_M_right
!= 0)
63 while (__x
->_M_left
!= 0)
68 _Rb_tree_node_base
* __y
= __x
->_M_parent
;
69 while (__x
== __y
->_M_right
)
74 if (__x
->_M_right
!= __y
)
80 const _Rb_tree_node_base
*
81 _Rb_tree_increment(const _Rb_tree_node_base
* __x
)
83 return _Rb_tree_increment(const_cast<_Rb_tree_node_base
*>(__x
));
87 _Rb_tree_decrement(_Rb_tree_node_base
* __x
)
89 if (__x
->_M_color
== _S_red
90 && __x
->_M_parent
->_M_parent
== __x
)
92 else if (__x
->_M_left
!= 0)
94 _Rb_tree_node_base
* __y
= __x
->_M_left
;
95 while (__y
->_M_right
!= 0)
101 _Rb_tree_node_base
* __y
= __x
->_M_parent
;
102 while (__x
== __y
->_M_left
)
105 __y
= __y
->_M_parent
;
112 const _Rb_tree_node_base
*
113 _Rb_tree_decrement(const _Rb_tree_node_base
* __x
)
115 return _Rb_tree_decrement(const_cast<_Rb_tree_node_base
*>(__x
));
119 _Rb_tree_rotate_left(_Rb_tree_node_base
* const __x
,
120 _Rb_tree_node_base
*& __root
)
122 _Rb_tree_node_base
* const __y
= __x
->_M_right
;
124 __x
->_M_right
= __y
->_M_left
;
125 if (__y
->_M_left
!=0)
126 __y
->_M_left
->_M_parent
= __x
;
127 __y
->_M_parent
= __x
->_M_parent
;
131 else if (__x
== __x
->_M_parent
->_M_left
)
132 __x
->_M_parent
->_M_left
= __y
;
134 __x
->_M_parent
->_M_right
= __y
;
136 __x
->_M_parent
= __y
;
140 _Rb_tree_rotate_right(_Rb_tree_node_base
* const __x
,
141 _Rb_tree_node_base
*& __root
)
143 _Rb_tree_node_base
* const __y
= __x
->_M_left
;
145 __x
->_M_left
= __y
->_M_right
;
146 if (__y
->_M_right
!= 0)
147 __y
->_M_right
->_M_parent
= __x
;
148 __y
->_M_parent
= __x
->_M_parent
;
152 else if (__x
== __x
->_M_parent
->_M_right
)
153 __x
->_M_parent
->_M_right
= __y
;
155 __x
->_M_parent
->_M_left
= __y
;
157 __x
->_M_parent
= __y
;
161 _Rb_tree_insert_and_rebalance(const bool __insert_left
,
162 _Rb_tree_node_base
* __x
,
163 _Rb_tree_node_base
* __p
,
164 _Rb_tree_node_base
& __header
)
166 _Rb_tree_node_base
*& __root
= __header
._M_parent
;
168 // Initialize fields in new node to insert.
169 __x
->_M_parent
= __p
;
172 __x
->_M_color
= _S_red
;
175 // Make new node child of parent and maintain root, leftmost and
177 // N.B. First node is always inserted left.
180 __p
->_M_left
= __x
; // also makes leftmost = __x when __p == &__header
182 if (__p
== &__header
)
184 __header
._M_parent
= __x
;
185 __header
._M_right
= __x
;
187 else if (__p
== __header
._M_left
)
188 __header
._M_left
= __x
; // maintain leftmost pointing to min node
194 if (__p
== __header
._M_right
)
195 __header
._M_right
= __x
; // maintain rightmost pointing to max node
199 && __x
->_M_parent
->_M_color
== _S_red
)
201 _Rb_tree_node_base
* const __xpp
= __x
->_M_parent
->_M_parent
;
203 if (__x
->_M_parent
== __xpp
->_M_left
)
205 _Rb_tree_node_base
* const __y
= __xpp
->_M_right
;
206 if (__y
&& __y
->_M_color
== _S_red
)
208 __x
->_M_parent
->_M_color
= _S_black
;
209 __y
->_M_color
= _S_black
;
210 __xpp
->_M_color
= _S_red
;
215 if (__x
== __x
->_M_parent
->_M_right
)
217 __x
= __x
->_M_parent
;
218 _Rb_tree_rotate_left(__x
, __root
);
220 __x
->_M_parent
->_M_color
= _S_black
;
221 __xpp
->_M_color
= _S_red
;
222 _Rb_tree_rotate_right(__xpp
, __root
);
227 _Rb_tree_node_base
* const __y
= __xpp
->_M_left
;
228 if (__y
&& __y
->_M_color
== _S_red
)
230 __x
->_M_parent
->_M_color
= _S_black
;
231 __y
->_M_color
= _S_black
;
232 __xpp
->_M_color
= _S_red
;
237 if (__x
== __x
->_M_parent
->_M_left
)
239 __x
= __x
->_M_parent
;
240 _Rb_tree_rotate_right(__x
, __root
);
242 __x
->_M_parent
->_M_color
= _S_black
;
243 __xpp
->_M_color
= _S_red
;
244 _Rb_tree_rotate_left(__xpp
, __root
);
248 __root
->_M_color
= _S_black
;
252 _Rb_tree_rebalance_for_erase(_Rb_tree_node_base
* const __z
,
253 _Rb_tree_node_base
& __header
)
255 _Rb_tree_node_base
*& __root
= __header
._M_parent
;
256 _Rb_tree_node_base
*& __leftmost
= __header
._M_left
;
257 _Rb_tree_node_base
*& __rightmost
= __header
._M_right
;
258 _Rb_tree_node_base
* __y
= __z
;
259 _Rb_tree_node_base
* __x
= 0;
260 _Rb_tree_node_base
* __x_parent
= 0;
262 if (__y
->_M_left
== 0) // __z has at most one non-null child. y == z.
263 __x
= __y
->_M_right
; // __x might be null.
265 if (__y
->_M_right
== 0) // __z has exactly one non-null child. y == z.
266 __x
= __y
->_M_left
; // __x is not null.
269 // __z has two non-null children. Set __y to
270 __y
= __y
->_M_right
; // __z's successor. __x might be null.
271 while (__y
->_M_left
!= 0)
277 // relink y in place of z. y is z's successor
278 __z
->_M_left
->_M_parent
= __y
;
279 __y
->_M_left
= __z
->_M_left
;
280 if (__y
!= __z
->_M_right
)
282 __x_parent
= __y
->_M_parent
;
283 if (__x
) __x
->_M_parent
= __y
->_M_parent
;
284 __y
->_M_parent
->_M_left
= __x
; // __y must be a child of _M_left
285 __y
->_M_right
= __z
->_M_right
;
286 __z
->_M_right
->_M_parent
= __y
;
292 else if (__z
->_M_parent
->_M_left
== __z
)
293 __z
->_M_parent
->_M_left
= __y
;
295 __z
->_M_parent
->_M_right
= __y
;
296 __y
->_M_parent
= __z
->_M_parent
;
297 std::swap(__y
->_M_color
, __z
->_M_color
);
299 // __y now points to node to be actually deleted
303 __x_parent
= __y
->_M_parent
;
305 __x
->_M_parent
= __y
->_M_parent
;
309 if (__z
->_M_parent
->_M_left
== __z
)
310 __z
->_M_parent
->_M_left
= __x
;
312 __z
->_M_parent
->_M_right
= __x
;
313 if (__leftmost
== __z
)
315 if (__z
->_M_right
== 0) // __z->_M_left must be null also
316 __leftmost
= __z
->_M_parent
;
317 // makes __leftmost == _M_header if __z == __root
319 __leftmost
= _Rb_tree_node_base::_S_minimum(__x
);
321 if (__rightmost
== __z
)
323 if (__z
->_M_left
== 0) // __z->_M_right must be null also
324 __rightmost
= __z
->_M_parent
;
325 // makes __rightmost == _M_header if __z == __root
326 else // __x == __z->_M_left
327 __rightmost
= _Rb_tree_node_base::_S_maximum(__x
);
330 if (__y
->_M_color
!= _S_red
)
332 while (__x
!= __root
&& (__x
== 0 || __x
->_M_color
== _S_black
))
333 if (__x
== __x_parent
->_M_left
)
335 _Rb_tree_node_base
* __w
= __x_parent
->_M_right
;
336 if (__w
->_M_color
== _S_red
)
338 __w
->_M_color
= _S_black
;
339 __x_parent
->_M_color
= _S_red
;
340 _Rb_tree_rotate_left(__x_parent
, __root
);
341 __w
= __x_parent
->_M_right
;
343 if ((__w
->_M_left
== 0 ||
344 __w
->_M_left
->_M_color
== _S_black
) &&
345 (__w
->_M_right
== 0 ||
346 __w
->_M_right
->_M_color
== _S_black
))
348 __w
->_M_color
= _S_red
;
350 __x_parent
= __x_parent
->_M_parent
;
354 if (__w
->_M_right
== 0
355 || __w
->_M_right
->_M_color
== _S_black
)
357 __w
->_M_left
->_M_color
= _S_black
;
358 __w
->_M_color
= _S_red
;
359 _Rb_tree_rotate_right(__w
, __root
);
360 __w
= __x_parent
->_M_right
;
362 __w
->_M_color
= __x_parent
->_M_color
;
363 __x_parent
->_M_color
= _S_black
;
365 __w
->_M_right
->_M_color
= _S_black
;
366 _Rb_tree_rotate_left(__x_parent
, __root
);
372 // same as above, with _M_right <-> _M_left.
373 _Rb_tree_node_base
* __w
= __x_parent
->_M_left
;
374 if (__w
->_M_color
== _S_red
)
376 __w
->_M_color
= _S_black
;
377 __x_parent
->_M_color
= _S_red
;
378 _Rb_tree_rotate_right(__x_parent
, __root
);
379 __w
= __x_parent
->_M_left
;
381 if ((__w
->_M_right
== 0 ||
382 __w
->_M_right
->_M_color
== _S_black
) &&
383 (__w
->_M_left
== 0 ||
384 __w
->_M_left
->_M_color
== _S_black
))
386 __w
->_M_color
= _S_red
;
388 __x_parent
= __x_parent
->_M_parent
;
392 if (__w
->_M_left
== 0 || __w
->_M_left
->_M_color
== _S_black
)
394 __w
->_M_right
->_M_color
= _S_black
;
395 __w
->_M_color
= _S_red
;
396 _Rb_tree_rotate_left(__w
, __root
);
397 __w
= __x_parent
->_M_left
;
399 __w
->_M_color
= __x_parent
->_M_color
;
400 __x_parent
->_M_color
= _S_black
;
402 __w
->_M_left
->_M_color
= _S_black
;
403 _Rb_tree_rotate_right(__x_parent
, __root
);
407 if (__x
) __x
->_M_color
= _S_black
;
413 _Rb_tree_black_count(const _Rb_tree_node_base
* __node
,
414 const _Rb_tree_node_base
* __root
)
418 unsigned int __sum
= 0;
421 if (__node
->_M_color
== _S_black
)
423 if (__node
== __root
)
425 __node
= __node
->_M_parent
;
431 _GLIBCXX_END_NAMESPACE