首先我们了解一下红黑树的性质:
在我们编写红黑树添加函数ADDRBT()之前 我们先编写几个工具函数
RBT* GetFather(RBT* pRoot, int id) 获得当前节点的父亲
- RBT* GetFather(RBT* pRoot, int id)
- {
- if (pRoot == NULL)
- {
- return nullptr;
- }
- while (pRoot != NULL)
- {
- if (pRoot->id > id)
- {
- if (pRoot->pLeft == NULL)
- {
- return pRoot;
- }
- pRoot = pRoot->pLeft;
-
- }
- else if (pRoot->id < id)
- {
- if (pRoot->pRight == NULL)
- {
- return pRoot;
- }
- pRoot = pRoot->pRight;
-
- }
- else
- {
-
- break;
- }
- }
- return nullptr;
- }
RBT* GetUncle(RBT* pRoot) 获得当前节点的叔叔
- RBT* GetUncle(RBT* pRoot)
- {
- if (pRoot == NULL || pRoot->pFather == NULL || pRoot->pFather->pFather == NULL)
- {
- return nullptr;
- }
- else
- {
- if (pRoot->pFather->pFather->pLeft == pRoot->pFather)
- {
- return pRoot->pFather->pFather->pRight;
- }
- else
- {
- return pRoot->pFather->pFather->pLeft;
- }
- }
-
-
- }
void RightRotate(RBT* pRBT,RBT*& pBoot) 右旋当前节点
- void RightRotate(RBT* pRBT, RBT*& pBoot)
- {
- if (pRBT == nullptr || pRBT->pLeft == nullptr)
- {
- return;
- }
- //标记不平衡节点 A
- RBT* pMark = pRBT;
- //标记不平衡节点的左 B
- RBT* pTemp = pRBT->pLeft;
- //x pMark->pFather E pTemp->pRight
-
- //三个孩子
- //不平衡节点的左->不平衡节点的 左的右 A->左=E
- pMark->pLeft = pTemp->pRight;
- //不平衡节点左的右->不平衡节点 B->右=A
- pTemp->pRight = pMark;
- //不平衡节点是不是根
-
- //是 不平衡的节点变为根
- if (pMark->pFather == nullptr)
- {
- pBoot = pTemp;
- }
- //不是 判断不平衡节点是父亲的左还是右 (A是父亲的左还是右)
- else
- {
- //左:
- //不平衡节点的父亲的左孩子->不平衡节点 X->左=B
- if (pMark->pFather->pLeft == pMark)
- {
- pMark->pFather->pLeft = pTemp;
- }
- //右:
- //不平衡节点的父亲的右孩子->不平衡节点 X->右=B
- else
- {
- pMark->pFather->pRight = pTemp;
- }
- }
-
- if (pMark->pLeft != nullptr)
- {
- pMark->pLeft->pFather = pMark;
- }
-
- pTemp->pFather = pMark->pFather;
-
- pMark->pFather = pTemp;
- }
void LeftRotate(RBT* pRBT, RBT*& pBoot) 左旋当前节点
- void LeftRotate(RBT* pRBT, RBT*& pBoot)
-
- {
- if (pRBT == nullptr || pRBT->pRight == nullptr)
- {
- return;
- }
-
- RBT* pMark = pRBT;
-
- RBT* pTemp = pRBT->pRight;
-
-
- pMark->pRight = pTemp->pLeft;
-
- pTemp->pLeft = pMark;
-
-
-
- if (pMark->pFather == nullptr)
- {
- pBoot = pTemp;
- }
- else
- {
-
- if (pMark->pFather->pLeft == pMark)
- {
- pMark->pFather->pLeft = pTemp;
- }
-
- else
- {
- pMark->pFather->pRight = pTemp;
-
- }
-
- }
-
-
-
- if (pMark->pRight != nullptr)
- {
- pMark->pRight->pFather = pMark;
- }
-
- pTemp->pFather = pMark->pFather;
-
- pMark->pFather = pTemp;
-
-
-
-
-
- }
-
-
然后我们开始定义 void AddRBT(RBT*& rpBoot, int id)函数
思想:
首先 我们把思路列出来 如下列代码注释
- void AddRBT(RBT*& rpBoot, int id)
- {
- RBT* pFather = GetFather(rpBoot, id);
- RBT* pMark = new RBT;
- pMark->color = RED;
- pMark->id = id;
- pMark->pFather = pFather;
-
- pMark->pLeft = NULL;
- pMark->pRight = NULL;
-
-
- //判断根是否为空
- //空 pMark赋给根
- if (rpBoot == NULL)
- {
- pMark->color = BLACK;
- rpBoot = pMark;
- return;
- }
- //非空 添加
- if (pFather->id > pMark->id)
- {
- pFather->pLeft = pMark;
- }
- else
- {
- pFather->pRight = pMark;
- }
- //分析
- while (1)
- {
- //先给pFather和pUncle重新赋值
- pFather = pMark->pFather;
-
- //判断父亲的颜色
- //黑 直接加
-
- if (pFather->color == BLACK)
- {
- return;
- }
- RBT* pUncle = GetUncle(pMark);
- //父亲为红 判断叔叔的颜色
-
-
- //叔叔为红
- //父亲和叔叔都变黑
- //爷爷变红
- //判断爷爷是否为根
- //为根 爷爷变黑
- //不为根 爷爷赋给标记 结束当前循环 重新对爷爷进行分析
-
-
- if (pUncle != nullptr && pUncle->color == RED)
- {
- pFather->color = BLACK;
- pUncle->color = BLACK;
-
- pFather->pFather->color = RED;
- pMark = pFather->pFather;
-
- if (pMark->pFather == NULL)
- {
- pMark->color = BLACK;
- return;
- }
- continue;
-
- }
- //叔叔为黑 (包含空)
- if (pUncle == NULL||pUncle->color==BLACK)
-
- {
-
- //判断父亲是爷爷的左还是右孩子
- //左 判断标记是父亲的左还是由节点
- //左 爷爷变红 父亲变黑 对爷爷节点右旋 结束
-
- //右 爷爷变红 父亲赋值给标记 对标记左旋
-
- //右 判断标记是父亲的左还是由节点
- //右 爷爷变红 父亲变黑 对爷爷节点左旋 结束
-
- //左 爷爷变红 父亲赋值给标记 对标记右旋
-
- if (pFather == pFather->pFather->pLeft)
- {
- if (pFather->pRight == pMark)
- {
-
- pMark = pFather;
-
- LeftRotate(pMark, rpBoot);
-
- }
-
- else
-
- {
-
- pMark->pFather->pFather->color = RED;
-
- pMark->pFather->color = BLACK;
-
- RightRotate(pMark->pFather->pFather, rpBoot);
-
- return;
-
- }
-
- }
- //右
- if (pFather == pFather->pFather->pRight)
-
- {
-
-
- if (pFather->pLeft == pMark)
-
- {
-
- pMark = pFather;
-
- RightRotate(pMark, rpBoot);
-
- }
-
- else
-
- {
-
- pMark->pFather->pFather->color = RED;
- pMark->pFather->color = BLACK;
- LeftRotate(pMark->pFather->pFather, rpBoot);
-
- return;
-
-
- }
-
-
-
-
- }
-
-
-
- }
-
- }
-
- }
delete函数思想:
代码
-
- RBT* GetDeleteNode(RBT* rpBoot, int id)
- {
- while (rpBoot)
- {
- if (id > rpBoot->id)
- {
-
- rpBoot = rpBoot->pRight;
- }
- else if (id < rpBoot->id)
- {
-
- rpBoot = rpBoot->pLeft;
- }
- else if(id == rpBoot->id)
- {
- return rpBoot;
- }
- }
- return NULL;
- }
-
- void DeteleRBT(RBT*& rpBoot, int nId)
- {
-
-
- RBT* pDel = GetDeleteNode(rpBoot, nId);
-
- if (pDel == NULL)
- {
- return;
- }
-
- if (pDel->pLeft != NULL && pDel->pRight != NULL)
- {
- RBT* pMark = pDel;
-
- pDel = pDel->pRight;
- while (pDel->pLeft!=NULL)
- {
- pDel = pDel->pLeft;
- }
-
-
-
- pMark->id = pDel->id;
- }
-
-
-
- if (pDel->pFather == NULL)
- //根
- {
- if (pDel->pLeft == NULL && pDel->pRight == NULL)
- //判断有没有一个孩子
- {
- rpBoot = NULL;
- //没有孩子
-
- }
- else
-
- {
- //有孩子
- rpBoot = pDel->pLeft != NULL ? pDel->pLeft : pDel->pRight;
- rpBoot->color = BLACK;
- rpBoot->pFather = NULL;
-
- }
- delete pDel;
- pDel = NULL;
- return;
- }
-
- RBT* pFather =pDel->pFather;
- //非根
- //分析节点颜色
-
-
- if (pDel->color == RED)
- //红 直接删
- {
-
- if (pDel == pFather->pLeft)
- {
- pFather->pLeft = NULL;
- }
- else
- {
- pFather->pRight = NULL;
- }
- delete pDel;
- pDel = NULL;
- return;
- }
-
- //黑 判断节点是否有孩子
-
- if (pDel->pLeft != NULL || pDel->pRight != NULL)
- //有孩子 一定是红孩子
- {
-
-
- //红孩子变黑 与爷爷相连
- RBT* pChild = pDel->pLeft != NULL ? pDel->pLeft : pDel->pRight;
- pChild->color = BLACK;
- pChild->pFather = pFather;
- if (pFather->pLeft==pDel)
- {
- pFather->pLeft = pChild;
- }
- else
- {
- pFather->pRight = pChild;
- }
- delete pDel;
- pDel = NULL;
- return;
-
-
-
-
- }
-
-
-
- //没孩子
- //先获得兄弟 删除节点
- RBT* pBrother = GetBrother(pDel);
- if (pFather->pLeft == pDel)
- {
- pFather->pLeft = NULL;
- }
- else
- {
- pFather->pRight = NULL;
- }
-
-
-
- //分析兄弟颜色 loop
- while (1)
-
- {
-
-
- if (pBrother->color == RED)
- //兄弟为红
- {
- //父亲变红 兄弟变黑 分析兄弟方向
- pFather->color = RED;
- pBrother->color = BLACK;
- if (pFather->pLeft == pBrother)//兄弟为父亲的左
- {
- //以父亲为支点 右旋
- RightRotate(pFather, rpBoot);
- pBrother = pFather->pLeft;
-
- }
- else //兄弟为父亲的右
- {
- //以父亲为支点 左旋
- LeftRotate(pFather, rpBoot);
- pBrother = pFather->pRight;
-
- }
- continue;
- }
-
- if (pBrother->color == BLACK)
- //兄弟为黑
- // 分析两个侄子的颜色
-
- {
- if ((pBrother->pLeft == NULL && pBrother->pRight == NULL) ||
- ((pBrother->pLeft != NULL && pBrother->pLeft->color == BLACK) &&
- (pBrother->pRight != NULL && pBrother->pRight->color == BLACK)))
- {
- //两个侄子全黑(包括全为空) 分析父亲颜色
- if (pFather->color == RED)
- {
- //父亲为红 :父亲变黑 兄弟变红 结束
- pFather->color = BLACK;
- pBrother->color = RED;
- return;
- }
- else
- {
- //父亲为黑 : 兄弟变红 父亲为新的标记 更换兄弟 标记为根的时候结束 不为根继续分析
-
- pBrother->color = RED;
- pDel = pFather;
-
- if (pDel->pFather == NULL)
- {
- return;
- }
-
- continue;
-
- }
- }
- //左侄子红右侄子黑(空) 分析兄弟方向
- if ((pBrother->pLeft != NULL && pBrother->pLeft->color == RED) &&
- (pBrother->pRight == NULL || pBrother->pRight->color == BLACK))
- {
- //兄弟是父亲的右 兄弟变红 左侄子变黑 一兄弟为支点右旋 继续分析
- if (pBrother == pFather->pRight)
- {
- pBrother->color = RED;
- pBrother->pLeft->color = BLACK;
- RightRotate(pBrother, rpBoot);
- pBrother = pFather->pRight;
- continue;
- }
- //兄弟是父亲的左 父亲的颜色给兄弟 父亲变黑 左侄子变黑 以父亲为支点右旋 结束
- if (pFather->pLeft == pBrother)
- {
- pBrother->color = pFather->color;
- pFather->color = BLACK;
- pBrother->pLeft->color = BLACK;
- RightRotate(pFather, rpBoot);
- return;
- }
- }
-
- //右侄子红 分析兄弟方向
- if (pBrother->pRight != NULL && pBrother->pRight->color == RED)
- //兄弟是父亲的左 兄弟变红 右侄子变黑 以兄弟为支点左旋 继续分析
- if (pBrother == pFather->pLeft)
- {
- pBrother->color = RED;
- pBrother->pRight->color = BLACK;
- LeftRotate(pBrother, rpBoot);
- pBrother = pFather->pLeft;
- continue;
- }
- //兄弟是父亲的右 父亲的颜色给兄弟 父亲变黑 右侄子变黑 以父亲为支点左旋 结束
- if (pFather->pRight == pBrother)
- {
- pBrother->color = pFather->color;
- pFather->color = BLACK;
- pBrother->pRight->color = BLACK;
- LeftRotate(pFather, rpBoot);
- return;
- }
- }
-
- }
-
-
- }
-
-
-
-
主函数中我们进行测试:
- RBT* Boot = NULL;
-
- int arr[] = { 11,2,14,1,7,15,5 ,8};
- for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
- {
- AddRBT(Boot, arr[i]);
- }
- inorder(Boot);
- cout << "----------" << endl;
- AddRBT(Boot, 4);
- /*RBT* pBrother = GetBrother(Boot->pRight);
- cout << pBrother->id << endl;*/
- inorder(Boot);
- cout << "----------" << endl;
-
- //DeteleRBT(Boot, 1);
- DeteleRBT(Boot,8);
- inorder(Boot);
- return 0;
这里我们添加了节点4 删除了节点8
执行结果如下:
完整代码如下
- #include
- #include
- using namespace std;
- //1.红黑树中所有的节点但不是红的就是黑的
- //2.
-
- enum COLOR { RED, BLACK };
- struct RBT
- {
- int id;
- RBT* pLeft;
- RBT* pRight;
- RBT* pFather;
- COLOR color;
-
- };
-
- RBT* GetFather(RBT* pRoot, int id)
- {
- if (pRoot == NULL)
- {
- return nullptr;
- }
- while (pRoot != NULL)
- {
-
- if (pRoot->id > id)
- {
-
- if (pRoot->pLeft == NULL)
- {
- return pRoot;
- }
- pRoot = pRoot->pLeft;
-
- }
- else if (pRoot->id < id)
- {
- if (pRoot->pRight == NULL)
- {
- return pRoot;
- }
- pRoot = pRoot->pRight;
-
- }
- else
- {
- cout << "不允许添加值相同的节点,数据有误" << endl;
- break;
- }
- }
- return nullptr;
- }
-
- RBT* GetUncle(RBT* pRoot)
- {
- if (pRoot == NULL || pRoot->pFather == NULL || pRoot->pFather->pFather == NULL)
- {
- return nullptr;
- }
-
- if (pRoot->pFather->pFather->pLeft == pRoot->pFather)
- {
- return pRoot->pFather->pFather->pRight;
- }
- else
- {
- return pRoot->pFather->pFather->pLeft;
- }
-
-
- }
-
- void RightRotate(RBT* pRBT, RBT*& pBoot)
- {
- if (pRBT == nullptr || pRBT->pLeft == nullptr)
- {
- return;
- }
- //标记不平衡节点 A
- RBT* pMark = pRBT;
- //标记不平衡节点的左 B
- RBT* pTemp = pRBT->pLeft;
- //x pMark->pFather E pTemp->pRight
-
- //三个孩子
- //不平衡节点的左->不平衡节点的 左的右 A->左=E
- pMark->pLeft = pTemp->pRight;
- //不平衡节点左的右->不平衡节点 B->右=A
- pTemp->pRight = pMark;
- //不平衡节点是不是根
-
- //是 不平衡的节点变为根
- if (pMark->pFather == nullptr)
- {
- pBoot = pTemp;
- }
- //不是 判断不平衡节点是父亲的左还是右 (A是父亲的左还是右)
- else
- {
- //左:
- //不平衡节点的父亲的左孩子->不平衡节点 X->左=B
- if (pMark->pFather->pLeft == pMark)
- {
- pMark->pFather->pLeft = pTemp;
- }
- //右:
- //不平衡节点的父亲的右孩子->不平衡节点 X->右=B
- else
- {
- pMark->pFather->pRight = pTemp;
- }
- }
-
- if (pMark->pLeft != nullptr)
- {
- pMark->pLeft->pFather = pMark;
- }
-
- pTemp->pFather = pMark->pFather;
-
- pMark->pFather = pTemp;
- }
-
-
- void LeftRotate(RBT* pRBT, RBT*& pBoot)
-
- {
- if (pRBT == nullptr || pRBT->pRight == nullptr)
- {
- return;
- }
-
- RBT* pMark = pRBT;
-
- RBT* pTemp = pRBT->pRight;
-
-
- pMark->pRight = pTemp->pLeft;
-
- pTemp->pLeft = pMark;
-
-
-
- if (pMark->pFather == nullptr)
- {
- pBoot = pTemp;
- }
- else
- {
-
- if (pMark->pFather->pLeft == pMark)
- {
- pMark->pFather->pLeft = pTemp;
- }
-
- else
- {
- pMark->pFather->pRight = pTemp;
-
- }
-
- }
-
-
-
- if (pMark->pRight != nullptr)
- {
- pMark->pRight->pFather = pMark;
- }
-
- pTemp->pFather = pMark->pFather;
-
- pMark->pFather = pTemp;
-
-
-
-
-
- }
-
-
- void AddRBT(RBT*& rpBoot, int id)
- {
- RBT* pFather = GetFather(rpBoot, id);
- RBT* pMark = new RBT;
- pMark->color = RED;
- pMark->id = id;
- pMark->pFather = pFather;
-
- pMark->pLeft = NULL;
- pMark->pRight = NULL;
-
-
- //判断根是否为空
- //空 pMark赋给根
- if (rpBoot == NULL)
- {
- pMark->color = BLACK;
- rpBoot = pMark;
- return;
- }
- //非空 添加
- if (pFather->id > pMark->id)
- {
- pFather->pLeft = pMark;
- }
- else
- {
- pFather->pRight = pMark;
- }
- //分析
- while (1)
- {
- //先给pFather和pUncle重新赋值
- pFather = pMark->pFather;
-
- //判断父亲的颜色
- //黑 直接加
-
- if (pFather->color == BLACK)
- {
- return;
- }
- RBT* pUncle = GetUncle(pMark);
- //父亲为红 判断叔叔的颜色
-
-
- //叔叔为红
- //父亲和叔叔都变黑
- //爷爷变红
- //判断爷爷是否为根
- //为根 爷爷变黑
- //不为根 爷爷赋给标记 结束当前循环 重新对爷爷进行分析
-
-
- if (pUncle != nullptr && pUncle->color == RED)
- {
- pFather->color = BLACK;
- pUncle->color = BLACK;
-
- pFather->pFather->color = RED;
- pMark = pFather->pFather;
-
- if (pMark->pFather == NULL)
- {
- pMark->color = BLACK;
- return;
- }
- continue;
-
- }
- //叔叔为黑 (包含空)
- if (pUncle == NULL||pUncle->color==BLACK)
-
- {
-
- //判断父亲是爷爷的左还是右孩子
- //左 判断标记是父亲的左还是由节点
- //左 爷爷变红 父亲变黑 对爷爷节点右旋 结束
-
- //右 爷爷变红 父亲赋值给标记 对标记左旋
-
- //右 判断标记是父亲的左还是由节点
- //右 爷爷变红 父亲变黑 对爷爷节点左旋 结束
-
- //左 爷爷变红 父亲赋值给标记 对标记右旋
-
- if (pFather == pFather->pFather->pLeft)
- {
- if (pFather->pRight == pMark)
- {
-
- pMark = pFather;
-
- LeftRotate(pMark, rpBoot);
-
- }
-
- else
-
- {
-
- pMark->pFather->pFather->color = RED;
-
- pMark->pFather->color = BLACK;
-
- RightRotate(pMark->pFather->pFather, rpBoot);
-
- return;
-
- }
-
- }
- //右
- if (pFather == pFather->pFather->pRight)
-
- {
-
-
- if (pFather->pLeft == pMark)
-
- {
-
- pMark = pFather;
-
- RightRotate(pMark, rpBoot);
-
- }
-
- else
-
- {
-
- pMark->pFather->pFather->color = RED;
- pMark->pFather->color = BLACK;
- LeftRotate(pMark->pFather->pFather, rpBoot);
-
- return;
-
-
- }
-
-
-
-
- }
-
-
-
- }
-
- }
-
- }
-
- RBT* GetBrother(RBT* rpBoot)
- {
- if (rpBoot == NULL || rpBoot->pFather == NULL)
-
- {
-
- return NULL;
- }
- return rpBoot == rpBoot->pFather->pLeft ? rpBoot->pFather->pRight : rpBoot->pFather->pLeft;
-
- }
- RBT* GetDeleteNode(RBT* rpBoot, int id)
- {
- while (rpBoot)
- {
- if (id > rpBoot->id)
- {
-
- rpBoot = rpBoot->pRight;
- }
- else if (id < rpBoot->id)
- {
-
- rpBoot = rpBoot->pLeft;
- }
- else if(id == rpBoot->id)
- {
- return rpBoot;
- }
- }
- return NULL;
- }
-
- void DeteleRBT(RBT*& rpBoot, int nId)
- {
-
-
- RBT* pDel = GetDeleteNode(rpBoot, nId);
-
- if (pDel == NULL)
- {
- return;
- }
-
- if (pDel->pLeft != NULL && pDel->pRight != NULL)
- {
- RBT* pMark = pDel;
-
- pDel = pDel->pRight;
- while (pDel->pLeft!=NULL)
- {
- pDel = pDel->pLeft;
- }
-
-
-
- pMark->id = pDel->id;
- }
-
-
-
- if (pDel->pFather == NULL)
- //根
- {
- if (pDel->pLeft == NULL && pDel->pRight == NULL)
- //判断有没有一个孩子
- {
- rpBoot = NULL;
- //没有孩子
-
- }
- else
-
- {
- //有孩子
- rpBoot = pDel->pLeft != NULL ? pDel->pLeft : pDel->pRight;
- rpBoot->color = BLACK;
- rpBoot->pFather = NULL;
-
- }
- delete pDel;
- pDel = NULL;
- return;
- }
-
- RBT* pFather =pDel->pFather;
- //非根
- //分析节点颜色
-
-
- if (pDel->color == RED)
- //红 直接删
- {
-
- if (pDel == pFather->pLeft)
- {
- pFather->pLeft = NULL;
- }
- else
- {
- pFather->pRight = NULL;
- }
- delete pDel;
- pDel = NULL;
- return;
- }
-
- //黑 判断节点是否有孩子
-
- if (pDel->pLeft != NULL || pDel->pRight != NULL)
- //有孩子 一定是红孩子
- {
-
-
- //红孩子变黑 与爷爷相连
- RBT* pChild = pDel->pLeft != NULL ? pDel->pLeft : pDel->pRight;
- pChild->color = BLACK;
- pChild->pFather = pFather;
- if (pFather->pLeft==pDel)
- {
- pFather->pLeft = pChild;
- }
- else
- {
- pFather->pRight = pChild;
- }
- delete pDel;
- pDel = NULL;
- return;
-
-
-
-
- }
-
-
-
- //没孩子
- //先获得兄弟 删除节点
- RBT* pBrother = GetBrother(pDel);
- if (pFather->pLeft == pDel)
- {
- pFather->pLeft = NULL;
- }
- else
- {
- pFather->pRight = NULL;
- }
-
-
-
- //分析兄弟颜色 loop
- while (1)
-
- {
-
-
- if (pBrother->color == RED)
- //兄弟为红
- {
- //父亲变红 兄弟变黑 分析兄弟方向
- pFather->color = RED;
- pBrother->color = BLACK;
- if (pFather->pLeft == pBrother)//兄弟为父亲的左
- {
- //以父亲为支点 右旋
- RightRotate(pFather, rpBoot);
- pBrother = pFather->pLeft;
-
- }
- else //兄弟为父亲的右
- {
- //以父亲为支点 左旋
- LeftRotate(pFather, rpBoot);
- pBrother = pFather->pRight;
-
- }
- continue;
- }
-
- if (pBrother->color == BLACK)
- //兄弟为黑
- // 分析两个侄子的颜色
-
- {
- if ((pBrother->pLeft == NULL && pBrother->pRight == NULL) ||
- ((pBrother->pLeft != NULL && pBrother->pLeft->color == BLACK) &&
- (pBrother->pRight != NULL && pBrother->pRight->color == BLACK)))
- {
- //两个侄子全黑(包括全为空) 分析父亲颜色
- if (pFather->color == RED)
- {
- //父亲为红 :父亲变黑 兄弟变红 结束
- pFather->color = BLACK;
- pBrother->color = RED;
- return;
- }
- else
- {
- //父亲为黑 : 兄弟变红 父亲为新的标记 更换兄弟 标记为根的时候结束 不为根继续分析
-
- pBrother->color = RED;
- pDel = pFather;
-
- if (pDel->pFather == NULL)
- {
- return;
- }
-
- continue;
-
- }
- }
- //左侄子红右侄子黑(空) 分析兄弟方向
- if ((pBrother->pLeft != NULL && pBrother->pLeft->color == RED) &&
- (pBrother->pRight == NULL || pBrother->pRight->color == BLACK))
- {
- //兄弟是父亲的右 兄弟变红 左侄子变黑 一兄弟为支点右旋 继续分析
- if (pBrother == pFather->pRight)
- {
- pBrother->color = RED;
- pBrother->pLeft->color = BLACK;
- RightRotate(pBrother, rpBoot);
- pBrother = pFather->pRight;
- continue;
- }
- //兄弟是父亲的左 父亲的颜色给兄弟 父亲变黑 左侄子变黑 以父亲为支点右旋 结束
- if (pFather->pLeft == pBrother)
- {
- pBrother->color = pFather->color;
- pFather->color = BLACK;
- pBrother->pLeft->color = BLACK;
- RightRotate(pFather, rpBoot);
- return;
- }
- }
-
- //右侄子红 分析兄弟方向
- if (pBrother->pRight != NULL && pBrother->pRight->color == RED)
- //兄弟是父亲的左 兄弟变红 右侄子变黑 以兄弟为支点左旋 继续分析
- if (pBrother == pFather->pLeft)
- {
- pBrother->color = RED;
- pBrother->pRight->color = BLACK;
- LeftRotate(pBrother, rpBoot);
- pBrother = pFather->pLeft;
- continue;
- }
- //兄弟是父亲的右 父亲的颜色给兄弟 父亲变黑 右侄子变黑 以父亲为支点左旋 结束
- if (pFather->pRight == pBrother)
- {
- pBrother->color = pFather->color;
- pFather->color = BLACK;
- pBrother->pRight->color = BLACK;
- LeftRotate(pFather, rpBoot);
- return;
- }
- }
-
- }
-
-
- }
-
-
-
-
-
-
- ostream& operator <<(ostream& os, COLOR color)
- {
- if (color == RED)
- {
- os << "红";
- }
- if (color == BLACK)
- {
- os << "黑";
- }
- return os;
- }
-
-
- void inorder(RBT*& Boot)
- {
- if (Boot == NULL)
- {
-
- return;
- }
- inorder(Boot->pLeft);
- cout << Boot->id << " " << Boot->color << endl;
- inorder(Boot->pRight);
- }
-
-
- int main()
- {
- RBT* Boot = NULL;
-
- int arr[] = { 11,2,14,1,7,15,5 ,8};
- for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
- {
- AddRBT(Boot, arr[i]);
- }
- inorder(Boot);
- cout << "----------" << endl;
- AddRBT(Boot, 4);
- /*RBT* pBrother = GetBrother(Boot->pRight);
- cout << pBrother->id << endl;*/
- inorder(Boot);
- cout << "----------" << endl;
- //存疑 :
- // Add节点4 之后 8的节点的父亲应该是11 代码中的8 的父亲是7 未能找到原因 ??
- // 解决这个问题 代码就差不多没问题了
- //DeteleRBT(Boot, 1);
- DeteleRBT(Boot,7);
- inorder(Boot);
- return 0;
- }