From 68d5ab3e0c38fe95c2aa3a14b4f164016e5b4083 Mon Sep 17 00:00:00 2001 From: Ron Wein Date: Sun, 14 May 2006 07:40:30 +0000 Subject: [PATCH] Fixed a bug in the swap(pos1, pos2) function. --- STL_Extension/include/CGAL/Multiset.h | 90 ++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/STL_Extension/include/CGAL/Multiset.h b/STL_Extension/include/CGAL/Multiset.h index 9070360a7f0..e3f7b9f3ae8 100644 --- a/STL_Extension/include/CGAL/Multiset.h +++ b/STL_Extension/include/CGAL/Multiset.h @@ -1355,6 +1355,14 @@ protected: */ void _swap (Node* node1_P, Node* node2_P); + /*! + * Swap the location two sibling nodes in the tree. + * \param node1_P The first node. + * \param node2_P The second node. + * \pre The two nodes have a common parent. + */ + void _swap_siblings (Node* node1_P, Node* node2_P); + /*! * Calculate the height of the sub-tree spanned by the given node. * \param nodeP The sub-tree root. @@ -2304,7 +2312,11 @@ void Multiset::swap (iterator pos1, _pred2_P->object) != SMALLER); // Perform the swap. - _swap (node1_P, node2_P); + if (node1_P->parentP == node2_P->parentP) + _swap_siblings (node1_P, node2_P); + else + _swap (node1_P, node2_P); + return; } @@ -3330,6 +3342,82 @@ void Multiset::_swap (Node* node1_P, return; } +//--------------------------------------------------------- +// Swap the location two sibling nodes in the tree. +// +template +void Multiset::_swap_siblings (Node* node1_P, + Node* node2_P) +{ + CGAL_multiset_assertion (_is_valid (node1_P)); + CGAL_multiset_assertion (_is_valid (node2_P)); + + // Store the properties of the first node. + typename Node::Node_color color1 = node1_P->color; + Node *right1_P = node1_P->rightP; + Node *left1_P = node1_P->leftP; + + // Copy the properties of the second node to the first node. + node1_P->color = node2_P->color; + + node1_P->rightP = node2_P->rightP; + if (_is_valid (node1_P->rightP)) + node1_P->rightP->parentP = node1_P; + + node1_P->leftP = node2_P->leftP; + if (_is_valid (node1_P->leftP)) + node1_P->leftP->parentP = node1_P; + + // Copy the stored properties of the first node to the second node. + node2_P->color = color1; + + node2_P->rightP = right1_P; + if (_is_valid (node2_P->rightP)) + node2_P->rightP->parentP = node2_P; + + node2_P->leftP = left1_P; + if (_is_valid (node2_P->leftP)) + node2_P->leftP->parentP = node2_P; + + // Swap the children of the common parent node. + Node *parent_P = node1_P->parentP; + Node *temp; + + CGAL_multiset_assertion (parent_P == node2_P->parentP); + + temp = parent_P->leftP; + parent_P->leftP = parent_P->rightP; + parent_P->rightP = temp; + + // If one of the swapped nodes used to be the tree minimum, update + // the properties of the fictitious before-the-begin node. + if (beginNode.parentP == node1_P) + { + beginNode.parentP = node2_P; + node2_P->leftP = &beginNode; + } + else if (beginNode.parentP == node2_P) + { + beginNode.parentP = node1_P; + node1_P->leftP = &beginNode; + } + + // If one of the swapped nodes used to be the tree maximum, update + // the properties of the fictitious past-the-end node. + if (endNode.parentP == node1_P) + { + endNode.parentP = node2_P; + node2_P->rightP = &endNode; + } + else if (endNode.parentP == node2_P) + { + endNode.parentP = node1_P; + node1_P->rightP = &endNode; + } + + return; +} + //--------------------------------------------------------- // Calculate the height of the subtree spanned by a given node. //