Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

qmap.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** $Id: qmap.cpp,v 1.2 2003/07/10 02:40:12 llornkcor Exp $
00003 **
00004 ** Implementation of QMap
00005 **
00006 ** Created : 990406
00007 **
00008 ** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
00009 **
00010 ** This file is part of the tools module of the Qt GUI Toolkit.
00011 **
00012 ** This file may be distributed under the terms of the Q Public License
00013 ** as defined by Trolltech AS of Norway and appearing in the file
00014 ** LICENSE.QPL included in the packaging of this file.
00015 **
00016 ** This file may be distributed and/or modified under the terms of the
00017 ** GNU General Public License version 2 as published by the Free Software
00018 ** Foundation and appearing in the file LICENSE.GPL included in the
00019 ** packaging of this file.
00020 **
00021 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
00022 ** licenses may use this file in accordance with the Qt Commercial License
00023 ** Agreement provided with the Software.
00024 **
00025 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00026 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00027 **
00028 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
00029 **   information about Qt Commercial License Agreements.
00030 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
00031 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00032 **
00033 ** Contact info@trolltech.com if any conditions of this licensing are
00034 ** not clear to you.
00035 **
00036 **********************************************************************/
00037 
00038 #include "qmap.h"
00039 
00040 typedef QMapNodeBase* NodePtr;
00041 typedef QMapNodeBase Node;
00042 
00043 
00044 void QMapPrivateBase::rotateLeft( NodePtr x, NodePtr& root)
00045 {
00046     NodePtr y = x->right;
00047     x->right = y->left;
00048     if (y->left !=0)
00049         y->left->parent = x;
00050     y->parent = x->parent;
00051     if (x == root)
00052         root = y;
00053     else if (x == x->parent->left)
00054         x->parent->left = y;
00055     else
00056         x->parent->right = y;
00057     y->left = x;
00058     x->parent = y;
00059 }
00060 
00061 
00062 void QMapPrivateBase::rotateRight( NodePtr x, NodePtr& root )
00063 {
00064     NodePtr y = x->left;
00065     x->left = y->right;
00066     if (y->right != 0)
00067         y->right->parent = x;
00068     y->parent = x->parent;
00069     if (x == root)
00070         root = y;
00071     else if (x == x->parent->right)
00072         x->parent->right = y;
00073     else
00074         x->parent->left = y;
00075     y->right = x;
00076     x->parent = y;
00077 }
00078 
00079 
00080 void QMapPrivateBase::rebalance( NodePtr x, NodePtr& root)
00081 {
00082     x->color = Node::Red;
00083     while ( x != root && x->parent->color == Node::Red ) {
00084         if ( x->parent == x->parent->parent->left ) {
00085             NodePtr y = x->parent->parent->right;
00086             if (y && y->color == Node::Red) {
00087                 x->parent->color = Node::Black;
00088                 y->color = Node::Black;
00089                 x->parent->parent->color = Node::Red;
00090                 x = x->parent->parent;
00091             } else {
00092                 if (x == x->parent->right) {
00093                     x = x->parent;
00094                     rotateLeft( x, root );
00095                 }
00096                 x->parent->color = Node::Black;
00097                 x->parent->parent->color = Node::Red;
00098                 rotateRight (x->parent->parent, root );
00099             }
00100         } else {
00101             NodePtr y = x->parent->parent->left;
00102             if ( y && y->color == Node::Red ) {
00103                 x->parent->color = Node::Black;
00104                 y->color = Node::Black;
00105                 x->parent->parent->color = Node::Red;
00106                 x = x->parent->parent;
00107             } else {
00108                 if (x == x->parent->left) { 
00109                     x = x->parent;
00110                     rotateRight( x, root );
00111                 }
00112                 x->parent->color = Node::Black;
00113                 x->parent->parent->color = Node::Red;
00114                 rotateLeft( x->parent->parent, root );
00115             }
00116         }
00117     }
00118     root->color = Node::Black;
00119 }
00120 
00121 
00122 NodePtr QMapPrivateBase::removeAndRebalance( NodePtr z, NodePtr& root,
00123                                              NodePtr& leftmost,
00124                                              NodePtr& rightmost )
00125 {
00126     NodePtr y = z;
00127     NodePtr x;
00128     NodePtr x_parent;
00129     if (y->left == 0) {
00130         x = y->right;
00131     } else {
00132         if (y->right == 0)
00133             x = y->left;
00134         else
00135             {
00136                 y = y->right;
00137                 while (y->left != 0)
00138                     y = y->left;
00139                 x = y->right;
00140             }
00141     }
00142     if (y != z) {
00143         z->left->parent = y; 
00144         y->left = z->left;
00145         if (y != z->right) {
00146             x_parent = y->parent;
00147             if (x)
00148                 x->parent = y->parent;
00149             y->parent->left = x;
00150             y->right = z->right;
00151             z->right->parent = y;
00152         } else {
00153             x_parent = y;  
00154         }
00155         if (root == z)
00156             root = y;
00157         else if (z->parent->left == z)
00158             z->parent->left = y;
00159         else 
00160             z->parent->right = y;
00161         y->parent = z->parent;
00162         // Swap the colors
00163         Node::Color c = y->color;
00164         y->color = z->color;
00165         z->color = c;
00166         y = z;
00167     } else {       
00168         x_parent = y->parent;
00169         if (x)
00170             x->parent = y->parent;   
00171         if (root == z)
00172             root = x;
00173         else if (z->parent->left == z)
00174             z->parent->left = x;
00175         else
00176             z->parent->right = x;
00177         if ( leftmost == z ) {
00178             if (z->right == 0)
00179                 leftmost = z->parent;
00180             else
00181                 leftmost = x->minimum();
00182         }
00183         if (rightmost == z) {
00184             if (z->left == 0)
00185                 rightmost = z->parent;  
00186             else
00187                 rightmost = x->maximum();
00188         }
00189     }
00190     if (y->color != Node::Red) { 
00191         while (x != root && (x == 0 || x->color == Node::Black)) {
00192             if (x == x_parent->left) {
00193                 NodePtr w = x_parent->right;
00194                 if (w->color == Node::Red) {
00195                     w->color = Node::Black;
00196                     x_parent->color = Node::Red;
00197                     rotateLeft(x_parent, root);
00198                     w = x_parent->right;
00199                 }
00200                 if ((w->left == 0 || w->left->color == Node::Black) &&
00201                     (w->right == 0 || w->right->color == Node::Black)) {
00202                     w->color = Node::Red;
00203                     x = x_parent;
00204                     x_parent = x_parent->parent;
00205                 } else {
00206                     if (w->right == 0 || w->right->color == Node::Black) {
00207                         if (w->left)
00208                             w->left->color = Node::Black;
00209                         w->color = Node::Red;
00210                         rotateRight(w, root);
00211                         w = x_parent->right;
00212                     }
00213                     w->color = x_parent->color;
00214                     x_parent->color = Node::Black;
00215                     if (w->right)
00216                         w->right->color = Node::Black;
00217                     rotateLeft(x_parent, root);
00218                     break;
00219                 }
00220             } else {
00221                 NodePtr w = x_parent->left;
00222                 if (w->color == Node::Red) {
00223                     w->color = Node::Black;
00224                     x_parent->color = Node::Red;
00225                     rotateRight(x_parent, root);
00226                     w = x_parent->left;
00227                 }
00228                 if ((w->right == 0 || w->right->color == Node::Black) &&
00229                     (w->left == 0 || w->left->color == Node::Black)) {
00230                     w->color = Node::Red;
00231                     x = x_parent;
00232                     x_parent = x_parent->parent;
00233                 } else {
00234                     if (w->left == 0 || w->left->color == Node::Black) {
00235                         if (w->right) 
00236                             w->right->color = Node::Black;
00237                         w->color = Node::Red;
00238                         rotateLeft(w, root);
00239                         w = x_parent->left;
00240                     }
00241                     w->color = x_parent->color;
00242                     x_parent->color = Node::Black;
00243                     if (w->left)
00244                         w->left->color = Node::Black;
00245                     rotateRight(x_parent, root);
00246                     break;
00247                 }
00248             }
00249         }
00250         if (x)
00251             x->color = Node::Black;
00252     }
00253     return y;
00254 }

Generated on Sat Nov 5 16:18:31 2005 for OPIE by  doxygen 1.4.2