红黑树删除操作
来源:互联网 发布: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$
- 红黑树(删除操作)
- 红黑树之删除操作
- 红黑树(3) - 删除操作
- 红黑树、插入删除操作
- 红黑树插入删除操作
- 红黑树删除操作
- 红黑树的添加删除操作
- 红黑树节点的删除操作
- 红黑树删除操作学习笔记
- 查找 -- 红黑树的删除操作
- 删除操作
- 今天完成了红黑树的删除操作。插入、删除完成。
- 红黑树——删除操作(未完成)
- 红黑树的插入删除操作图解
- 红黑书(三)红黑树的删除操作
- C++ 红黑树增加、删除等操作
- 浅谈红黑树的添加删除操作
- 红黑树的基本插入和删除操作
- AVL树
- template_lsearch_in_c
- java环境配置和java程序编写运行
- 高度重视农村小规模小学和教学点的管理和建设
- ToolBar+DrawerLayout实现左右双布局侧滑和动画返回控制显示抽屉布局
- 红黑树删除操作
- addslashes和mysql_escape_string,mysql_real_escape_string的区别
- Spark Broadcast概述
- centos7 nginx支持cgi
- SpringBoot 学习记录(十一): hazelcast+swagger2
- validate自定义验证
- 高斯消元学习笔记
- linux 定义别名 命令
- 人人店短信插件开发