最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

红黑树删除算法

SEO心得admin37浏览0评论
本文介绍了红黑树删除算法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

从算法导论第2版我得到这个删除算法:

/ *     RB-DELETE(T,Z)     1如果离开[Z] =零[T]或右边的[Z] =零[T]     2,则y←ž     3其他Ÿ←树后继(Z)     4如果离开[Y]≠零[T]     5,则x←离开[Y]     6别人进行x←权[Y]     7 P [X]←P [Y]     8如果p [Y] =零[T]     9然后根[T]←x     10否则如果y =左侧[P [Y]     11然后左键[P [Y]←x     12其他人的权利[P [Y]←x     13如果y!= Z     14然后键[Z]←键[Y]     15副本ÿ的卫星数据引入到z     16,如果颜色[Y] =黑色     17则RB-DELETE-FIXUP(T,X)     18返回是     * /

现在一些问题,这个算法,一是主要的问题是,如果你尝试建立树(你可以做到这一点的 )与节点1,2,3,4,5,6(放在这个顺序),然​​后删除节点2,行4,5和6这个算法返回nullptr(X == nullptr)。谁能帮我这个?

下面是辅助性的算法(来自同一本书):

TREE后继(X) 1,如果权[X]≠NIL 2然后返回树最小(右[X]) 3根Y←P [X] 4而在Y≠NIL和X =正确的[Y] 5先去做x←ÿ 6 Y←P [Y] 7返回是  树最小(X) 1,而离开[X]≠NIL 2先去做x←左[X] 3返回X  RB-DELETE-FIXUP(T,X)  1能够在X≠根[T]和颜色[X] =黑色  2做当x =左[P [X]  3则W←权[P [X]  4,如果颜色[W] = RED  然后5颜色[W]←BLACK▹案例1  6色[P [X]←RED▹案例1  7左旋转(T,P [X])▹案例1  8瓦特←权[P [X]]▹案例1  9,如果颜色[离开[W] =黑色和彩色[右[W] =黑色 那么10色[W]←RED▹案例2 11 XP [X]▹案例2 12否则,如果颜色[右[W] =黑色 13则颜色[离开[W]←BLACK▹案例3 14颜色[W]←RED▹案例3 15 RIGHT-旋转(T,W)▹案例3 16瓦特←权[P [X]]▹案例3 17色[W]←颜色[P [X]]▹案例4 18色[P [X]←BLACK▹案例4 19颜色[右[W]←BLACK▹案例4 20左旋转(T,P [X])▹案例4 21×←根[T]▹案例4 22其他(同然后用权利和第左交换) 23颜色[X]←黑 左旋转(T,X)  1年←权[X]▹设置年。  2右[X]←左[Y]▹转个Y左子树为X的右子树。  3 P [离开[Y]←x  4 P [Y]←P [X]▹链接X的父母为y。  5如果p [X] =零[T]  6然后根[T]←ÿ  7否则,如果X =左[P [X]  8然后左键[P [X]←ÿ  9其他权[P [X]←ÿ 10左[Y]←x▹放置X Y上的左边。 11 P [X]←ÿ RB-INSERT(T,Z)  1年零←[T]  2×←根[T]  3能够在X≠零[T]  4做ÿ←x  5,如果键[Z]<键[X]  6,则x←左[X]  7别人进行x←权[X]  8 P [Z]←ÿ  9如果y =零[T] 10再根[T]←ž 11否则,如果关键[Z]<键[Y] 12然后离开[Y]←ž 13别的吧[Y]←ž 14左[Z]←为零[T] 15右[Z]←为零[T] 16色[Z]←RED 17 RB-INSERT-FIXUP(T,Z) RB-INSERT-FIXUP(T,Z)  1,而颜色[P [Z] = RED  2做,如果P [Z] =左[P [P [Z]]]  3,则y←权[P [P [Z]]]  4,如果颜色[Y] = RED  5,然后颜色[P [Z]]←BLACK▹案例1  6色[Y]←BLACK▹案例1  7彩[P [P [Z]]]←RED▹案例1  8ž←P [P [Z]]▹案例1  9否则,如果Z =右[P [Z] 10则z←P [Z]▹案例2 11左旋转(T,Z)▹案例2 12色[P [Z]←BLACK▹案例3 13色[P [P [Z]]]←RED▹案例3 14 RIGHT-旋转(T,P [P [Z])▹案例3 15其他(同then子句                          与右和左的交换) 16色[根[T]←BLACK

实施

枚举颜色{黑,红};     模板<类重点>     结构节点     {         关键* KEY_;         颜色color_;         节点* PARENT_;         节点* left_;         节点* right_;         节点(密钥K,节点*父= nullptr,节点*左= nullptr,节点*右= nullptr):KEY_(新的关键[2]),             color_(红),             PARENT_(父),             left_(左),             right_(右)         {             KEY_ [0] = K表;             KEY_ [1] ='\ 0';         }     }; 模板<类重点> 类树 {     节点< Key与GT; * head_;     类型定义键* key_pointer;     类型定义节点< Key与GT; *指针;     类型定义节点<关键 - GT; value_type的; 上市:     树(密钥K):head_(新value_type的(K))     {         头_-> color_ =黑色;     }     〜树()     {         删除head_;     }     指针根()const的     {         自动根= head_;         而(根 - > PARENT_)         {             根=根 - > PARENT_;         }         返回根;     }     空根(指针根)     {         head_ =根;     }     指针父()const的     {         返回头_-> PARENT_;     }     无效的父(母指针)     {         头_-> PARENT_ =父母;     }     指针向左()const的     {         返回头_-> left_;     }     空左侧(指针左)     {         头_-> left_ =左;     }     指针向右()const的     {         返回头_-> right_;     }     空权(指针右)     {         头_-> right_ =权利;     }     key_pointer键()const的     {         返回头_-> KEY_;     } }; 模板<分类,类节点> 无效left_rotate(树* T,节点* X) {     自动Y = X轴和GT; right_;     X-> right_ = Y-GT; left_;     如果(Y-GT; left_)     {         Y-GT;左_-> PARENT_ = X;     }     Y-GT; PARENT_ = X-> PARENT_;     如果(X->!PARENT_)     {         T->根(Y);     }     否则,如果(X == X->母公司_-> left_)     {         X->母公司_-> left_ = Y;     }     其他     {         X->母公司_-> right_ = Y;     }     Y-GT; left_ = X;     X-> PARENT_ = Y; } 模板<分类,类节点> 无效right_rotate(树* T,节点* X) {     自动Y = X轴和GT; left_;     X-> left_ = Y-GT; right_;     如果(Y-GT; right_)     {         Y-GT;右_-> PARENT_ = X;     }     Y-GT; PARENT_ = X-> PARENT_;     如果(X->!PARENT_)     {         T->根(Y);     }     否则,如果(X == X->母公司_-> right_)     {         X->母公司_-> right_ = Y;     }     其他     {         X->母公司_-> left_ = Y;     }     Y-GT; right_ = X;     X-> PARENT_ = Y; } 模板<分类,类Node_Value> 无效插入(树* T,Node_Value N) {     自动Z = make_node(N);     汽车X = T->根();     decltype(Z)Y = nullptr;     而(X)     {         Y = X;         如果(* Z-> KEY_< * X-> KEY_)         {             X = X-> left_;         }         其他         {             X = X-> right_;         }     }     Z-> PARENT_ = Y;     如果(!Y)     {         T->根(Z);     }     其他     {         如果(* Z-> KEY_< * Y-GT; KEY_)         {             Y-GT; left_ = Z;         }         其他         {             Y-GT; right_ = Z;         }     }     Z-> left_ = nullptr;     Z-> right_ = nullptr;     Z-> color_ =红;     insert_fix_up(T,Z); } 模板<分类,类节点> 无效insert_fix_up(树* T,节点* Z) {     而(Z->母公司_-> color_ ==红)     {         如果(Z-> PARENT_ == Z->母公司_->母公司_-> left_)         {             自动Y = Z->母公司_->母公司_-> right_;             如果(Y-GT; color_ ==红)             {                 Z->母公司_-> color_ =黑色;                 Y-GT; color_ =黑色;                 Z->母公司_->母公司_-> color_ =红;                 Z = Z->母公司_-> PARENT_;             }             否则,如果(Z == Z->母公司_-> right_)             {                 Z = Z-> PARENT_;                 left_rotate(T,Z);             }             Z->母公司_-> color_ =黑色;             Z->母公司_->母公司_-> color_ =红;             right_rotate(T,Z->母公司_-> PARENT_);         }         其他         {             自动Y = Z->母公司_->母公司_-> left_;             如果(Y-GT; color_ ==红)             {                 Z->母公司_-> color_ =黑色;                 Y-GT; color_ =黑色;                 Z->母公司_->母公司_-> color_ =红;                 Z = Z->母公司_-> PARENT_;             }             否则,如果(Z == Z->母公司_-> left_)             {                 Z = Z-> PARENT_;                 right_rotate(T,Z);             }             Z->母公司_-> color_ =黑色;             Z->母公司_->母公司_-> color_ =红;             left_rotate(T,Z->母公司_-> PARENT_);         }     }     T->根() - > color_ =黑色; } 模板<类节点> 节点* tree_minimum(节点* X) {     而(X-> left_)     {         X = X-> left_;     }     返回X; } 模板<类节点> 节点* tree_successor(节点* X) {     如果(X-> right_)     {         返回tree_minimum(X-> right_);     }     自动Y = X轴和GT; PARENT_;     而(Y&安培;&放大器,X == Y-GT; right_)     {         X = Y;         Y = Y-GT; PARENT_;     }     返回是; } 模板<分类,类节点> 节点* rb_delete(树* T,节点* Z) {     节点* X = nullptr;     节点* Y = nullptr;     如果(Z->!left_ || Z-> right_)     {         Y = Z;     }     其他     {         Y = tree_successor(Z);     }     如果(Y-GT; left_)     {         X = Y-GT; left_;     }     其他     {         X = Y-GT; right_;     }     X-> PARENT_ = Y-GT; PARENT_;     如果(Y-GT;!PARENT_)     {         T->根(X);     }     否则,如果(Y == Y-GT;母公司_-> left_)     {         Y-GT;母公司_-> left_ = X;     }     其他     {         Y-GT;母公司_-> right_ = X;     }     如果(Y!= Z)     {         Z-> KEY_ = Y-GT; KEY_;     }     如果(Y-GT; color_ =黑)     {         rb_delete_fix_up(T,X);     }     返回是; } 模板<分类,类节点> 无效rb_delete_fix_up(树*& T公司,节点*放大器,X) {     而(X =叔>!根()&安培;&安培; x轴与GT; color_ ==黑色)     {         节点* W = nullptr;         如果(X == X->母公司_-> left_)         {             W = X轴和GT;母公司_-> right_;             如果(W-> color_ ==红)             {                 W-> color_ =黑色;                 X->母公司_-> color_ =红;                 left_rotate(T,X轴和GT; PARENT_);                 W = X轴和GT;母公司_-> right_;             }             如果(W->左_-> color_ ==黑色&安培;&安培; W->右_-> color_ ==黑)             {                 W-> color_ =红;                 X = X-> PARENT_;             }             否则,如果(W->右_-> color_ ==黑)             {                 W->左_-> color_ =黑色;                 W-> color_ =红;                 right_rotate(T,W);                 W = X轴和GT;母公司_-> right_;             }             W-> color_ = X->母公司_-> color_;             X->母公司_-> color_ =黑色;             W->右_-> color_ =黑色;             left_rotate(T,X轴和GT; PARENT_);             X = T->根();         }         其他         {                 W = X轴和GT;母公司_-> left_;             如果(W-> color_ ==红)             {                 W-> color_ =黑色;                 X->母公司_-> color_ =红;                 right_rotate(T,X轴和GT; PARENT_);                 W = X轴和GT;母公司_-> left_;             }             如果(W->右_-> color_ ==黑色&安培;&安培; W->左_-> color_ ==黑)             {                 W-> color_ =红;                 X = X-> PARENT_;             }             否则,如果(W->左_-> color_ ==黑)             {                 W->右_-> color_ =黑色;                 W-> color_ =红;                 left_rotate(T,W);                 W = X轴和GT;母公司_-> left_;             }             W-> color_ = X->母公司_-> color_;             X->母公司_-> color_ =黑色;             W->左_-> color_ =黑色;             right_rotate(T,X轴和GT; PARENT_);             X = T->根();         }     }     X-> color_ =黑色; } 模板<类重点> 节点<钥匙及GT * make_node(密钥k)的 {     返回新的节点<钥匙及GT;(K); } INT _tmain(INT ARGC,_TCHAR * argv的[]) {     自动T =新树< INT>(1);     插入(T,2);     插入(T,3);     插入(T,4);     插入(T,5);     插入(T,6);     rb_delete(T,T-和GT;左());     返回0; }

解决方案

对于一个版本RB树的不哨兵删除操作实现如下:

SWRedBlackNode删除(SWRedBlackTree树,SWRedBlackNode节点){     SWRedBlackNodeÿ;     如果(node._left == NULL || node._right == NULL){         Y =节点;     } 其他 {         Y = node.getSuccessor();     }     SWRedBlackNode X;     如果(y._left!= NULL){         X = y._left;     } 其他 {         X = y._right;     }     如果(X!= NULL){         x._parent = y._parent;     }     SWRedBlackNode xParent = y._parent;     布尔yIsLeft = FALSE;     如果(y._parent == NULL){         tree._root = X;     }否则,如果(Y == y._parent._left){         y._parent._left = X;         yIsLeft = TRUE;     } 其他 {         y._parent._right = X;         yIsLeft = FALSE;     }     如果(Y!=节点){         node._value = y._value;     }     如果(!y._isRed){         deleteFixUp(树,X,xParent,yIsLeft);     }     返回是; } 私人无效deleteFixUp(SWRedBlackTree树,SWRedBlackNode节点,SWRedBlackNode nodeParent,布尔nodeIsLeft){     而(节点= tree._root和放大器;!&安培; isBlack(节点)){         SWRedBlackNode瓦;         如果(nodeIsLeft){             W = nodeParent._right;             如果(isRed(瓦特)){                 w._isRed = FALSE;                 nodeParent._isRed = TRUE;                 leftRotate(树,nodeParent);                 W = nodeParent._right;             }             如果(isBlack(w._left)及&安培; isBlack(w._right)){                 w._isRed = TRUE;                 节点= nodeParent;                 nodeParent = node._parent;                 nodeIsLeft =(节点== nodeParent._left);             } 其他 {                 如果(isBlack(w._right)){                     w._left._isRed = FALSE;                     w._isRed = TRUE;                     rightRotate(树,W);                     W = nodeParent._right;                 }                 w._isRed = nodeParent._isRed;                 nodeParent._isRed = FALSE;                 如果(w._right!= NULL){                     w._right._isRed = FALSE;                 }                 leftRotate(树,nodeParent);                 节点= tree._root;                 nodeParent = NULL;             }         }其他{/ * nodeIsLeft ==假* /             W = nodeParent._left;             如果(isRed(瓦特)){                 w._isRed = FALSE;                 nodeParent._isRed = TRUE;                 rightRotate(树,nodeParent);                 W = nodeParent._left;             }             如果(isBlack(w._right)及&安培; isBlack(w._left)){                 w._isRed = TRUE;                 节点= nodeParent;                 nodeParent = node._parent;                 nodeIsLeft =(节点== nodeParent._left);             } 其他 {                 如果(isBlack(w._left)){                     w._right._isRed = FALSE;                     w._isRed = TRUE;                     leftRotate(树,W);                     W = nodeParent._left;                 }                 w._isRed = nodeParent._isRed;                 nodeParent._isRed = FALSE;                 如果(w._left!= NULL){                     w._left._isRed = FALSE;                 }                 rightRotate(树,nodeParent);                 节点= tree._root;                 nodeParent = NULL;             }         }     }     node._isRed = FALSE; }

这是在Java中,但可以很容易地移植到任何语言。

下面code是不同的关于您的实现:

嵌套在这里:

}其他{                 如果(isBlack(w._right)){

这里:

}其他{                 如果(isBlack(w._left)){

如果没有哨兵的东西在这里:

如果(X!= NULL){         x._parent = y._parent;     }     SWRedBlackNode xParent = y._parent;     布尔yIsLeft = FALSE;     如果(y._parent == NULL){         tree._root = X;     }否则,如果(Y == y._parent._left){         y._parent._left = X;         yIsLeft = TRUE;     } 其他 {         y._parent._right = X;         yIsLeft = FALSE;     }

然后在这里:

deleteFixUp(树,X,xParent,yIsLeft);

和 deleteFixUp() - 只认准使用 nodeParent 和 nodeIsLeft ,终于在这个地方:

如果(w._right!= NULL){                     w._right._isRed = FALSE;                 }

和这样的:

如果(w._left!= NULL){                     w._left._isRed = FALSE;                 }

From "Introduction to Algorithms 2nd edition" I got this deletion algorithm:

/* RB-DELETE(T, z) 1 if left[z] = nil[T] or right[z] = nil[T] 2 then y ← z 3 else y ← TREE-SUCCESSOR(z) 4 if left[y] ≠ nil[T] 5 then x ← left[y] 6 else x ← right[y] 7 p[x] ← p[y] 8 if p[y] = nil[T] 9 then root[T] ← x 10 else if y = left[p[y]] 11 then left[p[y]] ← x 12 else right[p[y]] ← x 13 if y != z 14 then key[z] ← key[y] 15 copy y's satellite data into z 16 if color[y] = BLACK 17 then RB-DELETE-FIXUP(T, x) 18 return y */

Now few problems with this algorithm, one main problem is that if you try to build tree ( you can do it here) with nodes 1,2,3,4,5,6 (placed in this order), and then delete node 2, lines 4,5 and 6 of this algorithm returns nullptr (x == nullptr). Can anyone help me with this?

Here are the helper algorithms (from same book):

TREE-SUCCESSOR(x) 1 if right[x] ≠ NIL 2 then return TREE-MINIMUM (right[x]) 3 y ← p[x] 4 while y ≠ NIL and x = right[y] 5 do x ← y 6 y ← p[y] 7 return y TREE-MINIMUM (x) 1 while left[x] ≠ NIL 2 do x ← left[x] 3 return x RB-DELETE-FIXUP(T, x) 1 while x ≠ root[T] and color[x] = BLACK 2 do if x = left[p[x]] 3 then w ← right[p[x]] 4 if color[w] = RED 5 then color[w] ← BLACK ▹ Case 1 6 color[p[x]] ← RED ▹ Case 1 7 LEFT-ROTATE(T, p[x]) ▹ Case 1 8 w ← right[p[x]] ▹ Case 1 9 if color[left[w]] = BLACK and color[right[w]] = BLACK 10 then color[w] ← RED ▹ Case 2 11 x p[x] ▹ Case 2 12 else if color[right[w]] = BLACK 13 then color[left[w]] ← BLACK ▹ Case 3 14 color[w] ← RED ▹ Case 3 15 RIGHT-ROTATE(T, w) ▹ Case 3 16 w ← right[p[x]] ▹ Case 3 17 color[w] ← color[p[x]] ▹ Case 4 18 color[p[x]] ← BLACK ▹ Case 4 19 color[right[w]] ← BLACK ▹ Case 4 20 LEFT-ROTATE(T, p[x]) ▹ Case 4 21 x ← root[T] ▹ Case 4 22 else (same as then clause with "right" and "left" exchanged) 23 color[x] ← BLACK LEFT-ROTATE(T, x) 1 y ← right[x] ▹ Set y. 2 right[x] ← left[y] ▹ Turn y's left subtree into x's right subtree. 3 p[left[y]] ← x 4 p[y] ← p[x] ▹ Link x's parent to y. 5 if p[x] = nil[T] 6 then root[T] ← y 7 else if x = left[p[x]] 8 then left[p[x]] ← y 9 else right[p[x]] ← y 10 left[y] ← x ▹ Put x on y's left. 11 p[x] ← y RB-INSERT(T, z) 1 y ← nil[T] 2 x ← root[T] 3 while x ≠ nil[T] 4 do y ← x 5 if key[z] < key[x] 6 then x ← left[x] 7 else x ← right[x] 8 p[z] ← y 9 if y = nil[T] 10 then root[T] ← z 11 else if key[z] < key[y] 12 then left[y] ← z 13 else right[y] ← z 14 left[z] ← nil[T] 15 right[z] ← nil[T] 16 color[z] ← RED 17 RB-INSERT-FIXUP(T, z) RB-INSERT-FIXUP(T, z) 1 while color[p[z]] = RED 2 do if p[z] = left[p[p[z]]] 3 then y ← right[p[p[z]]] 4 if color[y] = RED 5 then color[p[z]] ← BLACK ▹ Case 1 6 color[y] ← BLACK ▹ Case 1 7 color[p[p[z]]] ← RED ▹ Case 1 8 z ← p[p[z]] ▹ Case 1 9 else if z = right[p[z]] 10 then z ← p[z] ▹ Case 2 11 LEFT-ROTATE(T, z) ▹ Case 2 12 color[p[z]] ← BLACK ▹ Case 3 13 color[p[p[z]]] ← RED ▹ Case 3 14 RIGHT-ROTATE(T, p[p[z]]) ▹ Case 3 15 else (same as then clause with "right" and "left" exchanged) 16 color[root[T]] ← BLACK

IMPLEMENTATION

enum Color {Black,Red}; template<class Key> struct Node { Key* key_; Color color_; Node* parent_; Node* left_; Node* right_; Node(Key k,Node* parent = nullptr, Node* left = nullptr,Node* right = nullptr):key_(new Key[2]), color_(Red), parent_(parent), left_(left), right_(right) { key_[0] = k; key_[1] = '\0'; } }; template<class Key> class Tree { Node<Key>* head_; typedef Key* key_pointer; typedef Node<Key>* pointer; typedef Node<Key> value_type; public: Tree(Key k):head_(new value_type(k)) { head_->color_ = Black; } ~Tree() { delete head_; } pointer root()const { auto root = head_; while (root->parent_) { root = root->parent_; } return root; } void root(pointer root) { head_ = root; } pointer parent()const { return head_->parent_; } void parent(pointer parent) { head_->parent_ = parent; } pointer left()const { return head_->left_; } void left(pointer left) { head_->left_ = left; } pointer right()const { return head_->right_; } void right(pointer right) { head_->right_ = right; } key_pointer key()const { return head_->key_; } }; template<class Tree,class Node> void left_rotate(Tree* t, Node* x) { auto y = x->right_; x->right_ = y->left_; if (y->left_) { y->left_->parent_ = x; } y->parent_ = x->parent_; if (!x->parent_) { t->root(y); } else if(x == x->parent_->left_) { x->parent_->left_ = y; } else { x->parent_->right_ = y; } y->left_ = x; x->parent_ = y; } template<class Tree,class Node> void right_rotate(Tree* t, Node* x) { auto y = x->left_; x->left_ = y->right_; if (y->right_) { y->right_->parent_ = x; } y->parent_ = x->parent_; if (!x->parent_) { t->root(y); } else if(x == x->parent_->right_) { x->parent_->right_ = y; } else { x->parent_->left_ = y; } y->right_ = x; x->parent_ = y; } template<class Tree, class Node_Value> void insert(Tree* t, Node_Value n) { auto z = make_node(n); auto x = t->root(); decltype(z) y = nullptr; while(x) { y = x; if (*z->key_ < *x->key_) { x = x->left_; } else { x = x->right_; } } z->parent_ = y; if (!y) { t->root(z); } else { if (*z->key_ < *y->key_) { y->left_ = z; } else { y->right_ = z; } } z->left_ = nullptr; z->right_ = nullptr; z->color_ = Red; insert_fix_up(t,z); } template<class Tree, class Node> void insert_fix_up(Tree* t, Node* z) { while (z->parent_->color_ == Red) { if (z->parent_ == z->parent_->parent_->left_) { auto y = z->parent_->parent_->right_; if (y->color_ == Red) { z->parent_->color_ = Black; y->color_ = Black; z->parent_->parent_->color_ = Red; z = z->parent_->parent_; } else if(z == z->parent_->right_) { z = z->parent_; left_rotate(t,z); } z->parent_->color_ = Black; z->parent_->parent_->color_ = Red; right_rotate(t,z->parent_->parent_); } else { auto y = z->parent_->parent_->left_; if (y->color_ == Red) { z->parent_->color_ = Black; y->color_ = Black; z->parent_->parent_->color_ = Red; z = z->parent_->parent_; } else if(z == z->parent_->left_) { z = z->parent_; right_rotate(t,z); } z->parent_->color_ = Black; z->parent_->parent_->color_ = Red; left_rotate(t,z->parent_->parent_); } } t->root()->color_ = Black; } template<class Node> Node* tree_minimum(Node* x) { while (x->left_) { x = x->left_; } return x; } template<class Node> Node* tree_successor(Node* x) { if (x->right_) { return tree_minimum(x->right_); } auto y = x->parent_; while (y && x == y->right_) { x = y; y = y->parent_; } return y; } template<class Tree, class Node> Node* rb_delete(Tree* t,Node* z) { Node* x = nullptr; Node* y = nullptr; if (!z->left_ || !z->right_) { y = z; } else { y = tree_successor(z); } if (y->left_) { x = y->left_; } else { x = y->right_; } x->parent_ = y->parent_; if (!y->parent_) { t->root(x); } else if (y == y->parent_->left_) { y->parent_->left_ = x; } else { y->parent_->right_ = x; } if (y != z) { z->key_ = y->key_; } if (y->color_ = Black) { rb_delete_fix_up(t,x); } return y; } template<class Tree, class Node> void rb_delete_fix_up(Tree*& t,Node*& x) { while (x != t->root() && x->color_ == Black) { Node* w = nullptr; if (x == x->parent_->left_) { w = x->parent_->right_; if (w->color_ == Red) { w->color_ = Black; x->parent_->color_ = Red; left_rotate(t,x->parent_); w = x->parent_->right_; } if (w->left_->color_ == Black && w->right_->color_ == Black) { w->color_ = Red; x = x->parent_; } else if(w->right_->color_ == Black) { w->left_->color_ = Black; w->color_ = Red; right_rotate(t,w); w = x->parent_->right_; } w->color_ = x->parent_->color_; x->parent_->color_ = Black; w->right_->color_ = Black; left_rotate(t,x->parent_); x = t->root(); } else { w = x->parent_->left_; if (w->color_ == Red) { w->color_ = Black; x->parent_->color_ = Red; right_rotate(t,x->parent_); w = x->parent_->left_; } if (w->right_->color_ == Black && w->left_->color_ == Black) { w->color_ = Red; x = x->parent_; } else if(w->left_->color_ == Black) { w->right_->color_ = Black; w->color_ = Red; left_rotate(t,w); w = x->parent_->left_; } w->color_ = x->parent_->color_; x->parent_->color_ = Black; w->left_->color_ = Black; right_rotate(t,x->parent_); x = t->root(); } } x->color_ = Black; } template<class Key> Node<Key>* make_node(Key k) { return new Node<Key>(k); } int _tmain(int argc, _TCHAR* argv[]) { auto t = new Tree<int>(1); insert(t,2); insert(t,3); insert(t,4); insert(t,5); insert(t,6); rb_delete(t,t->left()); return 0; }

解决方案

For a version of rb-tree without sentinels the delete operation implementation is as follows:

SWRedBlackNode delete(SWRedBlackTree tree, SWRedBlackNode node) { SWRedBlackNode y; if (node._left == null || node._right == null) { y = node; } else { y = node.getSuccessor(); } SWRedBlackNode x; if (y._left != null) { x = y._left; } else { x = y._right; } if (x != null) { x._parent = y._parent; } SWRedBlackNode xParent = y._parent; boolean yIsLeft = false; if (y._parent == null) { tree._root = x; } else if (y == y._parent._left) { y._parent._left = x; yIsLeft = true; } else { y._parent._right = x; yIsLeft = false; } if (y != node) { node._value = y._value; } if (!y._isRed) { deleteFixUp(tree, x, xParent, yIsLeft); } return y; } private void deleteFixUp(SWRedBlackTree tree, SWRedBlackNode node, SWRedBlackNode nodeParent, boolean nodeIsLeft) { while (node != tree._root && isBlack(node)) { SWRedBlackNode w; if (nodeIsLeft) { w = nodeParent._right; if (isRed(w)) { w._isRed = false; nodeParent._isRed = true; leftRotate(tree, nodeParent); w = nodeParent._right; } if (isBlack(w._left) && isBlack(w._right)) { w._isRed = true; node = nodeParent; nodeParent = node._parent; nodeIsLeft = (node == nodeParent._left); } else { if (isBlack(w._right)) { w._left._isRed = false; w._isRed = true; rightRotate(tree, w); w = nodeParent._right; } w._isRed = nodeParent._isRed; nodeParent._isRed = false; if (w._right != null) { w._right._isRed = false; } leftRotate(tree, nodeParent); node = tree._root; nodeParent = null; } } else { /* nodeIsLeft == false */ w = nodeParent._left; if (isRed(w)) { w._isRed = false; nodeParent._isRed = true; rightRotate(tree, nodeParent); w = nodeParent._left; } if (isBlack(w._right) && isBlack(w._left)) { w._isRed = true; node = nodeParent; nodeParent = node._parent; nodeIsLeft = (node == nodeParent._left); } else { if (isBlack(w._left)) { w._right._isRed = false; w._isRed = true; leftRotate(tree, w); w = nodeParent._left; } w._isRed = nodeParent._isRed; nodeParent._isRed = false; if (w._left != null) { w._left._isRed = false; } rightRotate(tree, nodeParent); node = tree._root; nodeParent = null; } } } node._isRed = false; }

It's in Java but can easily be ported to any language.

The following code is different in respect to your implementation:

Nesting here:

} else { if (isBlack(w._right)) {

and here:

} else { if (isBlack(w._left)) {

Without-sentinel stuff here:

if (x != null) { x._parent = y._parent; } SWRedBlackNode xParent = y._parent; boolean yIsLeft = false; if (y._parent == null) { tree._root = x; } else if (y == y._parent._left) { y._parent._left = x; yIsLeft = true; } else { y._parent._right = x; yIsLeft = false; }

then here:

deleteFixUp(tree, x, xParent, yIsLeft);

and in deleteFixUp() - just look for usage of nodeParent and nodeIsLeft, and finally at this place:

if (w._right != null) { w._right._isRed = false; }

and this:

if (w._left != null) { w._left._isRed = false; }

发布评论

评论列表(0)

  1. 暂无评论