接着算法联系五,实现了红黑树的节点删除功能。
补充了五个函数,这里主要将 删除 和 删除修正两个函数给出,其它的就十分简单了。
//删除
RBNode* RBDelete(RBNode** proot, RBNode* pnode, RBNode* pguardNode);
//删除修正
void RBDeleteFixup(RBNode** proot, RBNode* pnode, RBNode* pguardNode);
//返回以节点为根的最小元素
RBNode* TreeMinimum(RBNode* pnode, RBNode* pguardNode);
//返回以节点为根的最大元素
RBNode* TreeMaxmum(RBNode* pnode, RBNode* pguardNode);
//返回节点的后继
RBNode* TreeSuccessor(RBNode* pnode, RBNode* pguardNode);
- //删除
- RBNode* RBDelete(RBNode** proot, RBNode* pnode, RBNode* pguardNode)
- {
- RBNode* y; //y为实际要被删除的节点
- RBNode* x; //x为y的孩子,y最多只有一个孩子
- if ( pnode->pLeft == pguardNode || pnode->pRight == pguardNode ) //左右孩子至少有一个为空
- {
- y = pnode;
- }
- else //左右孩子都不为空
- {
- y = TreeSuccessor(pnode,pguardNode); //y为pnode的后继节点
- }
- if ( y->pLeft != pguardNode ) //pnode的只有左孩子的情况
- {
- x = y->pLeft;
- }
- else
- {
- x = y->pRight;
- }
- //删除y开始
- x->pParent = y->pParent; //用x来替换y
- if ( y->pParent == pguardNode )
- {
- *proot = x;
- }
- else
- {
- if ( y == y->pParent->pLeft )
- {
- y->pParent->pLeft = x; //用x替换y
- }
- else
- {
- y->pParent->pRight = x;
- }
- }
- //删除y结束
- //将pnode的key用y的key替换
- if ( y != pnode )
- {
- pnode->key = y->key; //*这里没有将y的颜色赋值给pnode,这一点十分重要*//
- }
- if ( y->color == BLACK )
- {
- RBDeleteFixup( proot,x,pguardNode ); //修正性质5
- }
- return y;
- }
- //删除修正
- void RBDeleteFixup(RBNode** proot, RBNode* px, RBNode* pguardNode)
- {
- RBNode* w;
- while( px != *proot && px->color == BLACK && px != pguardNode )
- {
- if ( px == px->pParent->pLeft )
- {
- w = px->pParent->pRight;
- if ( w->color == RED ) //case1 px的兄弟是红色的
- {
- w->color = BLACK;
- px->pParent->color = RED;
- LeftRotate( proot, px->pParent, pguardNode );
- w = px->pParent->pRight;
- }
- if ( w->pLeft->color == BLACK && w->pRight->color == BLACK )
- { // case2 px的兄弟w是黑色的,并且w的两个孩子都是黑色的
- w->color = RED;
- px = px->pParent;
- }
- else
- {
- if ( w->pRight->color == BLACK )
- {
- //case3 px的兄弟w是黑色的,w的左孩子是红色的,右孩子是黑色的
- w->pLeft->color = BLACK;
- w->color = RED;
- RightRotate(proot,w,pguardNode);
- w = px->pParent->pRight;
- }
- //case4 px的兄弟w是黑色的,w的左孩子任意色,右孩子是红色的
- w->color = px->pParent->color;
- px->pParent->color = BLACK;
- w->pRight->color = BLACK;
- LeftRotate(proot,px->pParent,pguardNode);
- px = *proot;
- }
- }
- else // px == px->pParent->pRight
- {
- w = px->pParent->pLeft;
- if ( w->color == RED )
- {
- w->color = BLACK;
- px->pParent->color = RED;
- RightRotate( proot, px->pParent, pguardNode );
- w = px->pParent->pLeft;
- }
- if ( w->pLeft->color == BLACK && w->pRight->color == BLACK )
- {
- w->color = RED;
- px = px->pParent;
- }
- else
- {
- if ( w->pLeft->color == BLACK )
- {
- w->pRight->color = BLACK;
- w->color = RED;
- LeftRotate( proot, w, pguardNode );
- w = px->pParent->pLeft;
- }
- w->color = px->pParent->color;
- px->pParent->color = BLACK;
- w->pLeft->color = BLACK;
- RightRotate(proot, px->pParent, pguardNode );
- px = *proot;
- }
- }
- }//end while loop
- px->color = BLACK;
- }