00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
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 }