红黑树算法的思想与实现(一)
2015-06-05 13:53
183 查看
红黑树 是一颗二叉搜索树:树中每一个节点不是黑色就是红色。可以把一颗红黑树视为一颗扩充二叉树,用外部节点表示空指针。。。
有如下特性:
1.根节点和所有外部节点的颜色是黑色。
2.从根节点到外部节点的途中没有连续两个节点的颜色是红色。
3.所有从根节点到外部节点的路径上都有相同数目的黑色节点。
一、红黑树的搜索
对普通二叉搜索树进行搜索的时间复杂度为O(h), 对于红黑树则为O(lg n)--《以2为底n的对数》;
最差情况下AVL树的时间复杂度最优。
二、红黑树的插入
首先使用二叉搜索树的插入算法将一个元素插入到红黑树中,在插入过程中需要为其染色。
①、如果插入前是是空树,那么新元素将成为根节点,根据特征1,根节点必须染成黑色。
②、如果插入前树非空,若新节点被染成黑色,将违反红黑树特性3,所有从根到外部节点的路径上的黑色节点个数不等。因此 新插入节点将被染成红色,但这又可能违反红黑树的特性2,出现连续两个红色节点,因此需要重新平衡。
设新插入节点为u, 它的父节点和祖父节点分别为pu,gu,
②.1 若pu是黑色节点,则特性2没有被破坏,结束重新平衡的过程。
若pu是红色节点,则出现连续两个红色节点的情形,这时考察pu的兄弟节点
②.2.1pu的兄弟节点gr是红色节点, 此时gu为黑色,它有两个红色节点。交换节点gu和它的两个子女的颜色,将可能破坏红黑树特性2,
因此需先判断判断gu是否为根节点,若不是根节点,则交换gu与它的两个子女颜色;若gu是根节点,则只需将两个子女节点的颜色变为gu的颜色,而gu颜色无需改变。
②.2.2 pu的兄弟节点为黑色,此时又有两种情况。
---1>pu是gu的左子女,u是pu的 左子女。 ---->交换pu和gu的颜色,做一次右单旋转
u是pu的右子女。 ---->先交换u和gu的颜色,再左旋转,再右旋转。
---2>pu是gu的右子女,u是pu右子女。 ---->交换pu和gu的颜色,做一次左单旋转
u是pu的左子女。 ---->先交换u和gu的颜色,左旋转,右旋转
总归红黑树插入这么分 :1、黑父, 2、红父, 2.1、红叔, 2.2、黑叔。
//main函数
有如下特性:
1.根节点和所有外部节点的颜色是黑色。
2.从根节点到外部节点的途中没有连续两个节点的颜色是红色。
3.所有从根节点到外部节点的路径上都有相同数目的黑色节点。
一、红黑树的搜索
对普通二叉搜索树进行搜索的时间复杂度为O(h), 对于红黑树则为O(lg n)--《以2为底n的对数》;
最差情况下AVL树的时间复杂度最优。
二、红黑树的插入
首先使用二叉搜索树的插入算法将一个元素插入到红黑树中,在插入过程中需要为其染色。
①、如果插入前是是空树,那么新元素将成为根节点,根据特征1,根节点必须染成黑色。
②、如果插入前树非空,若新节点被染成黑色,将违反红黑树特性3,所有从根到外部节点的路径上的黑色节点个数不等。因此 新插入节点将被染成红色,但这又可能违反红黑树的特性2,出现连续两个红色节点,因此需要重新平衡。
设新插入节点为u, 它的父节点和祖父节点分别为pu,gu,
②.1 若pu是黑色节点,则特性2没有被破坏,结束重新平衡的过程。
若pu是红色节点,则出现连续两个红色节点的情形,这时考察pu的兄弟节点
②.2.1pu的兄弟节点gr是红色节点, 此时gu为黑色,它有两个红色节点。交换节点gu和它的两个子女的颜色,将可能破坏红黑树特性2,
因此需先判断判断gu是否为根节点,若不是根节点,则交换gu与它的两个子女颜色;若gu是根节点,则只需将两个子女节点的颜色变为gu的颜色,而gu颜色无需改变。
②.2.2 pu的兄弟节点为黑色,此时又有两种情况。
---1>pu是gu的左子女,u是pu的 左子女。 ---->交换pu和gu的颜色,做一次右单旋转
u是pu的右子女。 ---->先交换u和gu的颜色,再左旋转,再右旋转。
---2>pu是gu的右子女,u是pu右子女。 ---->交换pu和gu的颜色,做一次左单旋转
u是pu的左子女。 ---->先交换u和gu的颜色,左旋转,右旋转
总归红黑树插入这么分 :1、黑父, 2、红父, 2.1、红叔, 2.2、黑叔。
#include<iostream> #include<assert.h> using namespace std; typedef int Type; typedef enum Color{RED,BLACK}; typedef struct RBNode { Type data; Color color; struct RBNode *leftChild; struct RBNode *rightChild; struct RBNode *parent; }RBNode; typedef struct RBTree { RBNode *root; RBNode *nul; }RBTree; RBNode* buynode() { RBNode *s = new RBNode; assert(s != NULL); memset(s,0,sizeof(RBNode)); return s; } void InitRBTree(RBTree &t) { t.nul = buynode(); t.root = t.nul; t.nul->color = BLACK; t.nul->data = -1; } void RotateR(RBTree &t,RBNode *x) //右转,将根节点变为x的左子树节点 { RBNode *subR = x; x = subR->leftChild; subR->leftChild = x->rightChild; if(x->rightChild != t.nul) x->rightChild->parent = subR; x->rightChild = subR; if(subR->parent == t.nul) { t.root = x; } else if(subR == subR->parent->leftChild) subR->parent->leftChild = x; else subR->parent->rightChild = x; x->parent = subR->parent; subR->parent = x; } void RotateL(RBTree &t, RBNode *x) //根节点变为x的右子树 { RBNode *subL = x; x = subL->rightChild; subL->rightChild = x->leftChild; if(x->leftChild != t.nul) x->leftChild->parent = subL; x->leftChild = subL; if(subL->parent == t.nul) t.root = x; else if(subL->parent->rightChild == subL) subL->parent->rightChild = x; else subL->parent->leftChild = x; x->parent = subL->parent; subL->parent = x; } void insert_rebalance(RBTree &t, RBNode *u) { u->color = RED; RBNode *pu = u->parent; RBNode *gu = pu->parent; while(u!=t.root && pu->color==RED) { if(gu->leftChild == pu) { if(gu->rightChild && gu->rightChild->color == RED) //pu的兄弟节点存在且是红色 { //此时gu是黑色,他有两个红色子女节点 //交换gu和其两个子女的颜色 gu->rightChild->color = BLACK; pu->color = BLACK; if(gu->data != t.root->data) gu->color = RED; } else //pu的兄弟节点颜色为黑色 { if(pu->leftChild == u) //u、pu、gu都在一条左子树上 {//交换pu、gu的颜色 pu->color = BLACK; gu->color = RED; RotateR(t,gu); } else { gu->color = RED; u->color = BLACK; RotateL(t,pu); RotateR(t,gu); return; } } } else //gu->rightChild == pu { if(gu->leftChild && gu->leftChild->color == RED) //交换gu和其两个子女的颜色 { gu->leftChild->color = BLACK; pu->color = BLACK; if(gu->data != t.root->data) gu->color = RED; } else //pu的兄弟节点颜色为黑色 { if(pu->leftChild == u) { gu->color = RED; u->color = BLACK; RotateR(t,pu); RotateL(t,gu); return; } else { gu->color = RED; pu->color = BLACK; RotateL(t,gu); } } } } t.root->color = BLACK; return; } bool Insert(RBTree &t, const Type u) { RBNode *parent = t.nul; RBNode *p = t.root; while(p != t.nul) { if(t.root->data == u) return false; parent = p; if(parent->data < u) p = parent->rightChild; else p = parent->leftChild; } p = buynode(); p->data = u; p->color = RED; p->leftChild = t.nul; p->rightChild = t.nul; p->parent = t.nul; if(t.root == t.nul) { t.root = p; t.root->color = BLACK; return true; } if(parent->data > u) parent->leftChild = p; else parent->rightChild = p; p->parent = parent; insert_rebalance(t,p); return true; }
void remove_balance(RBTree &t, RBNode *p) { RBNode *u; RBNode *g = p->parent; RBNode *v = g->leftChild; RBNode *w = v->leftChild; RBNode *r = v->rightChild; if(p->rightChild == t.nul) //两种情况,1。p->leftChild!=t.nul 2.p->rightChild==t.nul { if(p->leftChild != t.nul) { u = p->leftChild; if(p->color == RED) { g->rightChild = u; } else { if(u->color == RED) u->color = BLACK; g->rightChild = u; if(v->color == BLACK) //v是u的左兄弟 { if(w && w->color==RED) //v的左子女为w { w->color = BLACK; g->color = BLACK; v->color = RED; RotateR(t, g); } else { if(r && r->color == RED) //w的有兄弟节点r { g->color = BLACK; RotateL(t, v); RotateR(t, g); } else { if(g->color == RED) { g->color = BLACK; v->color = RED; } else { RotateR(t, g); } } } } else //v->color = RED { RBNode* s = r->leftChild; if(s->color == RED) { RotateL(t, v); RotateR(t, g); } else //s->color==BLACK { RBNode* q = r->rightChild; if(q->color == RED) { RotateL(t,r); RotateL(t, v); RotateR(t, g); } else //q->color == BLACK { r->color = RED; v->color = BLACK; RotateR(t, v); } } } } } else //p->leftChild == t.nul && p->rightChild==t.nul { if(p == g->leftChild) { if(p->color == BLACK) { if(g->rightChild->color == RED) { } } g->leftChild = t.nul; } else { if(p->color == BLACK) { g->leftChild->color = BLACK; g->color = RED; RotateR(t, g); } g->rightChild = t.nul; } } //freenode(p); delete p; } else //p->rightChild != t.nul -->(p->leftChild==t.nul) { RBNode *pr=p->rightChild; if(p->color == RED) { if(g->rightChild == p) g->rightChild = pr; else g->leftChild = pr; } else //p->color==BLACK { } } } bool Remove(RBTree &t,const Type& u) { RBNode *p = t.root; while(p != t.nul) { if(p->data == u) { RBNode *tmp; //调整 if(p->leftChild != t.nul && p->rightChild != t.nul) { //RBNode* l = p->leftChild; tmp = p->rightChild; while(tmp->leftChild != t.nul) tmp = tmp->leftChild; p->data = tmp->data; remove_balance(t, tmp); } else //被删节点只有一个子女或没有子女 { remove_balance(t, p); } return true; } if(p->data > u) p = p->leftChild; else p = p->rightChild; } return false; }
void visit(RBNode *t) { cout<<t->data<<"("<<t->color<<")"<<" "; } void Print(RBTree &t) { RBNode *p = t.root; stack<RBNode*> st; while(p!=t.nul || !st.empty()) { if(p!=t.nul) { st.push(p); p = p->leftChild; } else { p = st.top(); st.pop(); visit(p); p = p->rightChild; } } cout<<endl; } size_t size(RBTree &t) { RBNode *p = t.root; stack<RBNode*> st; int count = 0; while(p!=t.nul || !st.empty()) { if(p!=t.nul) { st.push(p); p = p->leftChild; } else { p = st.top(); st.pop(); count++; p = p->rightChild; } } //cout<<count<<endl; return count; }
//main函数
#include "RBTree.h" void main() { int a[] = {10,12,3,8,11,5,20,7,18}; RBTree rbt; InitRBTree(rbt); for(int i=0; i<(sizeof(a)/sizeof(int)); ++i) { Insert(rbt,a[i]); } Remove(rbt, 10); Remove(rbt, 12); Remove(rbt, 18); Print(rbt); cout<<size(rbt)<<endl; }
相关文章推荐
- 自由选择的正能量
- java环境变量 maven 环境变量配置
- Window下zip压缩包的MySQL的启动与停止
- 几道智商类面试题
- 164-基于TI DSP TMS320C6455和Altera FPGA EP2S130的Full CameraLink PDS150接口板卡
- 文字截断
- jquery判断浏览器版本
- jquery.Sonline
- 去掉谷歌input外框
- iOS开发网络篇—监测网络状态
- GPS部标监控平台的功能设计(一)-功能列表
- spark将计算结果写入到mysql中
- input文本框 鼠标点击默认值消失,不输入离开鼠标恢复默认值
- 纯JS实现网页中自定义字体
- ie6双倍
- hack
- 06-图6. 公路村村通(30) java
- Linux mysql常用操作命令
- 设计模式四 命令模式
- ios 线程