红黑树的性质:
1.红黑树中的节点是黑色或者红色;
2.根节点一定是黑色
3.终端节点是黑色
4.没有2个红节点互为父子关系
5.从任意节点出发到其所能到达的各个终端节点的各条路径上黑节点数目必须完全相同
红黑树的创建:节点的初始颜色为红色,共7种情况
1.空 变为黑色 结束
2.父亲节点为黑 放入 结束
3.父亲节点为红
3.1叔叔节点为红
父->黑 叔->黑 爷->红
爷爷作为当前节点向上遍历
3.2 叔叔节点为黑
3.2.1父亲是爷爷 的左
3.2.1.1当前节点Z是父亲的右
父亲作为当前节点Z,
以当前节点Z为支点左旋
3.2.1.2 当前节点Z是父节点的左
父->黑 爷->红
以爷爷为支点右旋
结束
3.2.2父亲是爷爷的右
3.2.2.1当前节点Z是父亲的左
父亲作为当前节点Z
以Z为父的右旋
3.2.2.2当前节点Z是父亲的右
父->黑 爷->红
以爷爷为支点左旋
举个例子
代码:将根设为了全局变量,所有函数都可以直接改变他的值;左旋和右旋,在原来的基础上改动了一点点,变根的情况,更新rbt。
typedef struct node1 { int val; int color; struct node1* pLeft; struct node1* pRight; struct node1* pFather; } RBT; enum COLOR {RED,BLACK}; RBT* rbt = NULL; void RightSpin(RBT** ppTree) { RBT* pTree = *ppTree; RBT* ptmp = pTree->pLeft; pTree->pLeft = ptmp->pRight; if(ptmp->pRight) ptmp->pRight->pFather = pTree; ptmp->pRight = pTree; ptmp->pFather = pTree->pFather; if(pTree->pFather) { if(pTree == pTree->pFather->pRight) pTree->pFather->pRight = ptmp; else pTree->pFather->pLeft = ptmp; } else rbt = ptmp; pTree->pFather = ptmp; } void LeftSpin(RBT** ppTree) { RBT* pTree = *ppTree; RBT* ptmp = pTree->pRight; pTree->pRight = ptmp->pLeft; if(ptmp->pLeft) ptmp->pLeft->pFather = pTree; ptmp->pLeft = pTree; ptmp->pFather = pTree->pFather; if(pTree->pFather) { if(pTree == pTree->pFather->pRight) pTree->pFather->pRight = ptmp; else pTree->pFather->pLeft = ptmp; } else rbt = ptmp; pTree->pFather = ptmp; } RBT* Find(RBT* pRBT,int num) { if(pRBT == NULL) return NULL; while(pRBT) { if(pRBT->val == num) return NULL; else if(pRBT->val > num) { if(pRBT->pLeft) pRBT = pRBT->pLeft; else return pRBT; } else { if(pRBT->pRight) pRBT = pRBT->pRight; else return pRBT; } } } RBT* GetUncle(RBT* ptmp) { if(ptmp->pFather == ptmp->pFather->pFather->pLeft) return ptmp->pFather->pFather->pRight; else return ptmp->pFather->pFather->pLeft; } void InsertNode(RBT* pRBT, int num) { RBT* ptmp = (RBT*)malloc(sizeof(RBT)); ptmp->val = num; ptmp->color = RED; ptmp->pLeft = NULL; ptmp->pRight = NULL; ptmp->pFather = NULL; //查找 RBT* pfather = Find(pRBT,num); //空树 if(pRBT == NULL) { ptmp->color = BLACK; rbt = ptmp; return; } if(pfather->val > num) pfather->pLeft = ptmp; else pfather->pRight = ptmp; ptmp->pFather = pfather; //父节点为黑色 if(pfather->color == BLACK) { return; } RBT* pGrandfather = NULL; RBT* pUncle = NULL; //父节点为红色 while(pfather->color == RED) { pGrandfather = pfather->pFather; pUncle = GetUncle(ptmp); //叔叔为红色 if(pUncle != NULL && pUncle->color == RED ) { pfather->color = BLACK; pUncle->color = BLACK; pGrandfather->color = RED; ptmp = pGrandfather; pfather = ptmp->pFather; if(pfather == NULL) { ptmp->color = BLACK; return; } continue; } //没有叔叔或叔叔是黑色 if(pUncle == NULL || pUncle->color == BLACK) { //父为爷左 if(pfather == pGrandfather->pLeft) { //当前节点为父右 if(ptmp == pfather->pRight) { ptmp = pfather; LeftSpin(&ptmp); pfather = ptmp->pFather; continue; } //当前节点为父左 if(ptmp == pfather->pLeft) { pfather->color = BLACK; pGrandfather->color = RED; RightSpin(&pGrandfather); break; } } if(pfather == pGrandfather->pRight) { if(ptmp == pfather->pLeft) { ptmp = pfather; RightSpin(&ptmp); pfather = ptmp->pFather; continue; } if(ptmp == pfather->pRight) { pfather->color = BLACK; pGrandfather->color = RED; LeftSpin(&pGrandfather); break; } } } } rbt->color =BLACK; }