1 父子节点之间不能出现两个连续的红节点 2 任何一个节点向下遍历到其子孙的叶子节点,所经过的黑节点个数必须相等 */
| 209 | 2 任何一个节点向下遍历到其子孙的叶子节点,所经过的黑节点个数必须相等 |
| 210 | */ |
| 211 | void insert_fixup(RBTreeNode* z) |
| 212 | { |
| 213 | // 处理父节点是红色,父子同为红色冲突了 |
| 214 | while (z->p->color == RED) { |
| 215 | // 父节点在左边 |
| 216 | if (z->p->isLeft()) { |
| 217 | // 找到叔叔 |
| 218 | auto y = z->p->brother(); |
| 219 | // case 1 |
| 220 | if (y->color == RED) { |
| 221 | // printf("insert left case 1\n"); |
| 222 | // 父亲和叔叔都是红色,把他们都变成黑色 |
| 223 | z->p->color = BLACK; |
| 224 | y->color = BLACK; |
| 225 | // 把祖父变成红色 |
| 226 | z->p->p->color = RED; |
| 227 | z = z->p->p; |
| 228 | } else { |
| 229 | // case 2 3 |
| 230 | // 父亲是红色,叔叔是黑色 |
| 231 | if (z->isRight()) { |
| 232 | // printf("insert left case 2\n"); |
| 233 | // z在右边就左旋,z指向父节点 |
| 234 | z = z->p; |
| 235 | // 左旋父节点 |
| 236 | leftRotate(z); |
| 237 | } |
| 238 | // printf("insert left case 3\n"); |
| 239 | // 父亲设置为黑色 |
| 240 | z->p->color = BLACK; |
| 241 | // 把祖父变成红色 |
| 242 | z->p->p->color = RED; |
| 243 | // 右旋祖父节点 |
| 244 | rightRotate(z->p->p); |
| 245 | } |
| 246 | } else { |
| 247 | auto y = z->p->brother(); |
| 248 | // case 1 |
| 249 | if (y->color == RED) { |
| 250 | // printf("insert right case 1\n"); |
| 251 | z->p->color = BLACK; |
| 252 | y->color = BLACK; |
| 253 | z->p->p->color = RED; |
| 254 | z = z->p->p; |
| 255 | } else { |
| 256 | if (z->isLeft()) { |
| 257 | // printf("insert right case 2\n"); |
| 258 | z = z->p; |
| 259 | rightRotate(z); |
| 260 | } |
| 261 | |
| 262 | // printf("insert right case 3\n"); |
| 263 | z->p->color = BLACK; |
| 264 | z->p->p->color = RED; |
| 265 | leftRotate(z->p->p); |
| 266 | } |
| 267 | } |
| 268 | } |