mirror of
https://github.com/boostorg/intrusive.git
synced 2025-08-02 14:04:36 +02:00
Simplified rebalancing code extracting common operations to a local variable
This commit is contained in:
@@ -364,13 +364,14 @@ class avltree_algorithms
|
|||||||
node_ptr x(xnode), x_parent(xnode_parent);
|
node_ptr x(xnode), x_parent(xnode_parent);
|
||||||
for (node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)) {
|
for (node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)) {
|
||||||
const balance x_parent_balance = NodeTraits::get_balance(x_parent);
|
const balance x_parent_balance = NodeTraits::get_balance(x_parent);
|
||||||
|
node_ptr const x_parent_left(NodeTraits::get_left(x_parent));
|
||||||
if(x_parent_balance == NodeTraits::zero()){
|
if(x_parent_balance == NodeTraits::zero()){
|
||||||
NodeTraits::set_balance(x_parent,
|
NodeTraits::set_balance( x_parent
|
||||||
(x == NodeTraits::get_right(x_parent) ? NodeTraits::negative() : NodeTraits::positive()));
|
, x == x_parent_left ? NodeTraits::positive() : NodeTraits::negative() );
|
||||||
break; // the height didn't change, let's stop here
|
break; // the height didn't change, let's stop here
|
||||||
}
|
}
|
||||||
else if(x_parent_balance == NodeTraits::negative()){
|
else if(x_parent_balance == NodeTraits::negative()){
|
||||||
if (x == NodeTraits::get_left(x_parent)) {
|
if (x == x_parent_left) {
|
||||||
NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced
|
NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced
|
||||||
x = x_parent;
|
x = x_parent;
|
||||||
x_parent = NodeTraits::get_parent(x_parent);
|
x_parent = NodeTraits::get_parent(x_parent);
|
||||||
@@ -378,7 +379,7 @@ class avltree_algorithms
|
|||||||
else {
|
else {
|
||||||
// x is right child
|
// x is right child
|
||||||
// a is left child
|
// a is left child
|
||||||
node_ptr a = NodeTraits::get_left(x_parent);
|
node_ptr a = x_parent_left;
|
||||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(a);
|
BOOST_INTRUSIVE_INVARIANT_ASSERT(a);
|
||||||
if (NodeTraits::get_balance(a) == NodeTraits::positive()) {
|
if (NodeTraits::get_balance(a) == NodeTraits::positive()) {
|
||||||
// a MUST have a right child
|
// a MUST have a right child
|
||||||
@@ -441,38 +442,38 @@ class avltree_algorithms
|
|||||||
NodeTraits::set_balance(x, NodeTraits::zero());
|
NodeTraits::set_balance(x, NodeTraits::zero());
|
||||||
// Rebalance.
|
// Rebalance.
|
||||||
for(node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)){
|
for(node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)){
|
||||||
const balance x_parent_balance = NodeTraits::get_balance(NodeTraits::get_parent(x));
|
node_ptr const x_parent(NodeTraits::get_parent(x));
|
||||||
|
node_ptr const x_parent_left(NodeTraits::get_left(x_parent));
|
||||||
|
const balance x_parent_balance = NodeTraits::get_balance(x_parent);
|
||||||
if(x_parent_balance == NodeTraits::zero()){
|
if(x_parent_balance == NodeTraits::zero()){
|
||||||
// if x is left, parent will have parent->bal_factor = negative
|
// if x is left, parent will have parent->bal_factor = negative
|
||||||
// else, parent->bal_factor = NodeTraits::positive()
|
// else, parent->bal_factor = NodeTraits::positive()
|
||||||
NodeTraits::set_balance( NodeTraits::get_parent(x)
|
NodeTraits::set_balance( x_parent, x == x_parent_left
|
||||||
, x == NodeTraits::get_left(NodeTraits::get_parent(x))
|
? NodeTraits::negative() : NodeTraits::positive() );
|
||||||
? NodeTraits::negative() : NodeTraits::positive() );
|
x = x_parent;
|
||||||
x = NodeTraits::get_parent(x);
|
|
||||||
}
|
}
|
||||||
else if(x_parent_balance == NodeTraits::positive()){
|
else if(x_parent_balance == NodeTraits::positive()){
|
||||||
// if x is a left child, parent->bal_factor = zero
|
// if x is a left child, parent->bal_factor = zero
|
||||||
if (x == NodeTraits::get_left(NodeTraits::get_parent(x)))
|
if (x == x_parent_left)
|
||||||
NodeTraits::set_balance(NodeTraits::get_parent(x), NodeTraits::zero());
|
NodeTraits::set_balance(x_parent, NodeTraits::zero());
|
||||||
else{ // x is a right child, needs rebalancing
|
else{ // x is a right child, needs rebalancing
|
||||||
if (NodeTraits::get_balance(x) == NodeTraits::negative())
|
if (NodeTraits::get_balance(x) == NodeTraits::negative())
|
||||||
rotate_right_left(NodeTraits::get_parent(x), header);
|
rotate_right_left(x_parent, header);
|
||||||
else
|
else
|
||||||
rotate_left(NodeTraits::get_parent(x), header);
|
rotate_left(x_parent, header);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if(x_parent_balance == NodeTraits::negative()){
|
else if(x_parent_balance == NodeTraits::negative()){
|
||||||
// if x is a left child, needs rebalancing
|
// if x is a left child, needs rebalancing
|
||||||
if (x == NodeTraits::get_left(NodeTraits::get_parent(x))) {
|
if (x == x_parent_left) {
|
||||||
if (NodeTraits::get_balance(x) == NodeTraits::positive())
|
if (NodeTraits::get_balance(x) == NodeTraits::positive())
|
||||||
rotate_left_right(NodeTraits::get_parent(x), header);
|
rotate_left_right(x_parent, header);
|
||||||
else
|
else
|
||||||
rotate_right(NodeTraits::get_parent(x), header);
|
rotate_right(x_parent, header);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
NodeTraits::set_balance(NodeTraits::get_parent(x), NodeTraits::zero());
|
NodeTraits::set_balance(x_parent, NodeTraits::zero());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@@ -486,18 +487,20 @@ class avltree_algorithms
|
|||||||
// balancing...
|
// balancing...
|
||||||
const balance c_balance = NodeTraits::get_balance(c);
|
const balance c_balance = NodeTraits::get_balance(c);
|
||||||
const balance zero_balance = NodeTraits::zero();
|
const balance zero_balance = NodeTraits::zero();
|
||||||
|
const balance posi_balance = NodeTraits::positive();
|
||||||
|
const balance nega_balance = NodeTraits::negative();
|
||||||
NodeTraits::set_balance(c, zero_balance);
|
NodeTraits::set_balance(c, zero_balance);
|
||||||
if(c_balance == NodeTraits::negative()){
|
if(c_balance == nega_balance){
|
||||||
NodeTraits::set_balance(a, NodeTraits::positive());
|
NodeTraits::set_balance(a, posi_balance);
|
||||||
NodeTraits::set_balance(b, zero_balance);
|
NodeTraits::set_balance(b, zero_balance);
|
||||||
}
|
}
|
||||||
else if(c_balance == zero_balance){
|
else if(c_balance == zero_balance){
|
||||||
NodeTraits::set_balance(a, zero_balance);
|
NodeTraits::set_balance(a, zero_balance);
|
||||||
NodeTraits::set_balance(b, zero_balance);
|
NodeTraits::set_balance(b, zero_balance);
|
||||||
}
|
}
|
||||||
else if(c_balance == NodeTraits::positive()){
|
else if(c_balance == posi_balance){
|
||||||
NodeTraits::set_balance(a, zero_balance);
|
NodeTraits::set_balance(a, zero_balance);
|
||||||
NodeTraits::set_balance(b, NodeTraits::negative());
|
NodeTraits::set_balance(b, nega_balance);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached
|
BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached
|
||||||
|
@@ -10,31 +10,6 @@
|
|||||||
// See http://www.boost.org/libs/intrusive for documentation.
|
// See http://www.boost.org/libs/intrusive for documentation.
|
||||||
//
|
//
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// The internal implementation of red-black trees is based on that of SGI STL
|
|
||||||
// stl_tree.h file:
|
|
||||||
//
|
|
||||||
// Copyright (c) 1996,1997
|
|
||||||
// Silicon Graphics Computer Systems, Inc.
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, distribute and sell this software
|
|
||||||
// and its documentation for any purpose is hereby granted without fee,
|
|
||||||
// provided that the above copyright notice appear in all copies and
|
|
||||||
// that both that copyright notice and this permission notice appear
|
|
||||||
// in supporting documentation. Silicon Graphics makes no
|
|
||||||
// representations about the suitability of this software for any
|
|
||||||
// purpose. It is provided "as is" without express or implied warranty.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Copyright (c) 1994
|
|
||||||
// Hewlett-Packard Company
|
|
||||||
//
|
|
||||||
// Permission to use, copy, modify, distribute and sell this software
|
|
||||||
// and its documentation for any purpose is hereby granted without fee,
|
|
||||||
// provided that the above copyright notice appear in all copies and
|
|
||||||
// that both that copyright notice and this permission notice appear
|
|
||||||
// in supporting documentation. Hewlett-Packard Company makes no
|
|
||||||
// representations about the suitability of this software for any
|
|
||||||
// purpose. It is provided "as is" without express or implied warranty.
|
|
||||||
//
|
//
|
||||||
// The tree destruction algorithm is based on Julienne Walker and The EC Team code:
|
// The tree destruction algorithm is based on Julienne Walker and The EC Team code:
|
||||||
//
|
//
|
||||||
@@ -421,14 +396,16 @@ class rbtree_algorithms
|
|||||||
bstree_algo::rotate_left(x_parent, header);
|
bstree_algo::rotate_left(x_parent, header);
|
||||||
w = NodeTraits::get_right(x_parent);
|
w = NodeTraits::get_right(x_parent);
|
||||||
}
|
}
|
||||||
if((!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()) &&
|
node_ptr const w_left (NodeTraits::get_left(w));
|
||||||
(!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black())){
|
node_ptr const w_right(NodeTraits::get_right(w));
|
||||||
|
if((!w_left || NodeTraits::get_color(w_left) == NodeTraits::black()) &&
|
||||||
|
(!w_right || NodeTraits::get_color(w_right) == NodeTraits::black())){
|
||||||
NodeTraits::set_color(w, NodeTraits::red());
|
NodeTraits::set_color(w, NodeTraits::red());
|
||||||
x = x_parent;
|
x = x_parent;
|
||||||
x_parent = NodeTraits::get_parent(x_parent);
|
x_parent = NodeTraits::get_parent(x_parent);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()){
|
if(!w_right || NodeTraits::get_color(w_right) == NodeTraits::black()){
|
||||||
NodeTraits::set_color(NodeTraits::get_left(w), NodeTraits::black());
|
NodeTraits::set_color(NodeTraits::get_left(w), NodeTraits::black());
|
||||||
NodeTraits::set_color(w, NodeTraits::red());
|
NodeTraits::set_color(w, NodeTraits::red());
|
||||||
bstree_algo::rotate_right(w, header);
|
bstree_algo::rotate_right(w, header);
|
||||||
@@ -451,14 +428,16 @@ class rbtree_algorithms
|
|||||||
bstree_algo::rotate_right(x_parent, header);
|
bstree_algo::rotate_right(x_parent, header);
|
||||||
w = NodeTraits::get_left(x_parent);
|
w = NodeTraits::get_left(x_parent);
|
||||||
}
|
}
|
||||||
if((!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()) &&
|
node_ptr const w_left (NodeTraits::get_left(w));
|
||||||
(!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black())){
|
node_ptr const w_right(NodeTraits::get_right(w));
|
||||||
|
if((!w_right || NodeTraits::get_color(w_right) == NodeTraits::black()) &&
|
||||||
|
(!w_left || NodeTraits::get_color(w_left) == NodeTraits::black())){
|
||||||
NodeTraits::set_color(w, NodeTraits::red());
|
NodeTraits::set_color(w, NodeTraits::red());
|
||||||
x = x_parent;
|
x = x_parent;
|
||||||
x_parent = NodeTraits::get_parent(x_parent);
|
x_parent = NodeTraits::get_parent(x_parent);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()){
|
if(!w_left || NodeTraits::get_color(w_left) == NodeTraits::black()){
|
||||||
NodeTraits::set_color(NodeTraits::get_right(w), NodeTraits::black());
|
NodeTraits::set_color(NodeTraits::get_right(w), NodeTraits::black());
|
||||||
NodeTraits::set_color(w, NodeTraits::red());
|
NodeTraits::set_color(w, NodeTraits::red());
|
||||||
bstree_algo::rotate_left(w, header);
|
bstree_algo::rotate_left(w, header);
|
||||||
|
Reference in New Issue
Block a user