红黑树删除操作

来源:互联网 发布:python django教程 编辑:程序博客网 时间:2024/06/05 16:56

红黑树删除操作:

红黑树要删除某个key值时,首先还是要查找该key值在树中的位置,查找方法和搜索二叉树方法相同.

要删除的结点分为两种情况:

1.有左右两个孩子都存在.两个孩子都存在时,在该节点的右子树中寻找其直接后继,找到后用其值替换要删除节点的值,然后问题转化为删除该节点的直接后继,直接后继是有一个右孩子或者没有孩子节点.

2.只有一个孩子或者没有子孩子.

以上两种均归纳为最多只有一个孩子节点的节点,只要将其仅有的一个孩子节点及其子树或者NULL直接提上来就行,删除的节点如果是红色则不会影响树的黑高,如果是黑色节点,则会影响树的黑高,树的平衡必然被打破,所以要进行调整.

现在将前面所说的提上来的节点(也就是删除节点的孩子节点,即删除了那个节点以后那个位置上的节点)以下称为x,  x 的兄弟节点记为w,如果x为红色节点则直接将红色节点更改为黑色,则又重新平衡,调整完成,如果x为黑色节点(即NULL)这种情况比较复杂 ,分为4种情况处理:

1.如果x的兄弟节点w是红色的,则x和w的父亲节点p一定是黑色的而且w的两个孩子也是黑色的(非null)则只要将p和w做一次左旋转并改变w的颜色为红色即平衡.



2.x的兄弟节点w是黑色(非NULL)且两个子节点是黑色(null),则将w变为红色,这样p节点的子树平衡.将x = x->parent,即上移,又回到了1.2.3.4的情况(以new 的x的子树还是少了一个黑色节点)同样的去检查,如果x为红色则将变为黑色调整完成,如果是黑色,则继续去检查x的new的兄弟节点是什么颜色.....


3.w的左孩子节点是红色,右节点是黑色(null),w和x的父亲节点p可红可黑,对w做一次左旋转,并调整颜色,则成为4的情况.



4.w的右孩子是红色,左边孩子是黑色(null).将x的父亲节点做一次左旋转,然后更改颜色,x的父亲p 为黑色,w为红色,则调整完成.


typedef int Type;typedef enum{RED=0,  BLACK}COLOR;typedef struct RBNode{COLOR color;Type  data;RBNode *parent;RBNode *leftChild;RBNode *rightChild;}RBNode;typedef struct RBTree{RBNode *root;RBNode *NIL;}RBTree;RBNode* _Buynode(Type v){RBNode *s = (RBNode*)malloc(sizeof(RBNode));assert(s != NULL);memset(s, 0, sizeof(RBNode));s->data = v;s->color = RED;return s;}void InitRBTree(RBTree &t){t.NIL = _Buynode(0);t.root = t.NIL;t.NIL->color = BLACK;}void LeftRotate(RBTree &t, RBNode *p){RBNode *s = p->rightChild;p->rightChild = s->leftChild;if(s->leftChild != t.NIL)s->leftChild->parent = p;s->parent = p->parent;if(p->parent == t.NIL)t.root = s;else if(p == p->parent->leftChild)p->parent->leftChild = s;elsep->parent->rightChild = s;s->leftChild = p;p->parent = s;}void RightRotate(RBTree &t, RBNode *p){RBNode *s = p->leftChild;p->leftChild = s->rightChild;if(s->rightChild != t.NIL)s->rightChild->parent = p;s->parent = p->parent;if(p->parent == t.NIL)t.root = s;else if(p == p->parent->leftChild)p->parent->leftChild = s;elsep->parent->rightChild = s;s->rightChild = p;p->parent = s;}void Insert_Fixup(RBTree &t, RBNode *z){RBNode *y;while(z->parent->color == RED){if(z->parent == z->parent->parent->leftChild){y = z->parent->parent->rightChild;if(y->color == RED){z->parent->color = BLACK;y->color = BLACK;z->parent->parent->color = RED;z = z->parent->parent;continue;}else if(z == z->parent->rightChild){z = z->parent;LeftRotate(t, z);}z->parent->color = BLACK;z->parent->parent->color = RED;RightRotate(t, z->parent->parent);}else{y = z->parent->parent->leftChild;if(y->color == RED){z->parent->color = BLACK;y->color = BLACK;z->parent->parent->color = RED;z = z->parent->parent;continue;}else if(z == z->parent->leftChild){z = z->parent;RightRotate(t, z);}z->parent->color = BLACK;z->parent->parent->color = RED;LeftRotate(t, z->parent->parent);}}t.root->color = BLACK;}bool Insert(RBTree &t, Type x){RBNode *pr = t.NIL;RBNode *s = t.root;while(s != t.NIL){if(x == s->data)return false;pr = s;if(x < s->data)s = s->leftChild;elses = s->rightChild;}RBNode *q = _Buynode(x);q->parent = pr;q->leftChild = t.NIL;q->rightChild = t.NIL;q->color = RED;if(pr == t.NIL)t.root = q;else if(x < pr->data)pr->leftChild = q;elsepr->rightChild = q;Insert_Fixup(t, q);return true;}RBNode* _Next(RBTree &t, RBNode *p){if(p!=t.NIL && p->rightChild!=t.NIL){p = p->rightChild;while(p->leftChild != t.NIL)p = p->leftChild;}return p;}void Delete_Fixup(RBTree &t, RBNode *&x){RBNode *w;while(x!=t.root && x->color==BLACK){if(x == x->parent->leftChild){w = x->parent->rightChild;if(w->color == RED){w->color = BLACK;x->parent->color = RED;LeftRotate(t, x->parent);}if(w->leftChild->color==BLACK && w->rightChild->color==BLACK){w->color = RED;x = x->parent;}else if(w->rightChild->color == BLACK){w->leftChild->color = BLACK;w->color = RED;RightRotate(t, w);w = x->parent->rightChild;}w->color = x->parent->color;x->parent->color = BLACK;w->rightChild->color = BLACK;LeftRotate(t, x->parent);x = t.root;}else{w = x->parent->leftChild;if(w->color == RED){w->color = BLACK;x->parent->color = RED;RightRotate(t, x->parent);}if(w->leftChild->color==BLACK && w->rightChild->color==BLACK){w->color = RED;x = x->parent;}else if(w->leftChild->color == BLACK){w->rightChild->color = BLACK;w->color = RED;LeftRotate(t, w);w = x->parent->leftChild;}w->color = x->parent->color;x->parent->color = BLACK;w->leftChild->color = BLACK;RightRotate(t, x->parent);x = t.root;}}x->color = BLACK;}bool Remove(RBTree &t, Type key){RBNode *p = t.root;RBNode *y;RBNode *s;while(p!=t.NIL && p->data!=key){if(key < p->data)p = p->leftChild;elsep = p->rightChild;}//if(p->leftChild!=t.NIL || p->rightChild!=t.NIL)//y = p;//else//y = _Next(t, p);if(p->leftChild!=t.NIL && p->rightChild!=t.NIL)y = _Next(t, p);elsey = p;if(y->leftChild != t.NIL)s = y->leftChild;elses = y->rightChild;s->parent = y->parent;if(y->parent == t.NIL)t.root = s;else if(y == y->parent->leftChild)y->parent->leftChild = s;elsey->parent->rightChild = s;if(y != p)p->data = y->data;if(y->color == BLACK)Delete_Fixup(t, s);delete y;return true;}tianxintong@txt:~/git/shujia/Code@Bao/Test7_13_RBTree_C$ 




原创粉丝点击