//等我后续复习红黑树会画出所涉及到的情况,具体说一下这是如何来的,其实简单来说就一直寻找最简单的情况进行分析。
#include<stdio.h>
#include<stdlib.h>
enum COLOR{RED,BLACK};//创建颜色RED 0 , BLACK 1
//创建树的子节点
typedef struct Tree{
int nValue;
int nColor;
struct Tree *pFather;
struct Tree *pLeft;
struct Tree *pRight;
}RBT;
void AddNode(int nNum);
void Traverse(RBT *pTree);
void RightRotate(RBT **pTree);//右旋转
void LeftRotate(RBT **pTree);
void CreateTree(int arr[], int nLength);
RBT *FindNode(RBT *pTree, int nNum);
RBT *GetNode(RBT *pTree);
void DelNode(RBT *pTree, int nNum);
RBT *Search(RBT *pTree, int nNum);
RBT *pRBT = NULL;//建立树根
RBT *Search(RBT *pTree, int nNum)
{
while(pTree)
{
if(pTree->nValue == nNum){
return pTree;
}else if(pTree->nValue > nNum){
pTree = pTree->pLeft;
}else{
pTree = pTree->pRight;
}
}
return NULL;
}
void DelNode(RBT *pTree, int nNum)
{
RBT *pTemp = NULL;
pTemp = Search(pTree,nNum);
if(pTemp == NULL)return;
RBT *pMark = NULL;
//删除就是将左得最右或者右的最左替换要删除的
if(pTemp->pLeft != NULL && pTemp->pRight != NULL){
pMark = pTemp;
pTemp = pTemp->pLeft;
while(pTemp->pRight != NULL){
pTemp = pTemp->pRight;
}
pMark->nValue = pTemp->nValue;
}
RBT *pNode = pTemp->pFather;
if(pNode == NULL && pTemp->pLeft == NULL && pTemp->pRight == NULL){
pRBT = NULL;
free(pTemp);
pTemp = NULL;
return;
}
if(pNode == NULL && (pTemp->pLeft != NULL || pTemp->pRight != NULL)){
pRBT = pTemp->pLeft ? pTemp->pLeft : pTemp->pRight;
pRBT->nColor = BLACK;
pRBT->pFather = NULL;
free(pTemp);
pTemp = NULL;
return;
}
//感觉有问题,这个部分感觉少了情况
if(pTemp->nColor == RED){
if(pNode->pLeft == pTemp){
pNode->pLeft = NULL;
}else{
pNode->pRight = NULL;
}
free(pTemp);
pTemp = NULL;
return;
}
if(pTemp->nColor == BLACK && (pTemp->pLeft != NULL || pTemp->pRight != NULL)){
if(pTemp == pNode->pLeft){
pNode->pLeft = pTemp->pLeft ? pTemp->pLeft : pTemp->pRight;
pNode->pLeft->nColor = BLACK;
pNode->pLeft->pFather = pNode->pFather;
}else{
pNode->pRight = pTemp->pRight ? pTemp->pRight : pTemp->pLeft;
pNode->pRight->pFather = pNode->pFather;
pNode->pRight->nColor = BLACK;
}
free(pTemp);
pTemp = NULL;
return;
}
RBT *pBrother = GetNode(pTemp);
if(pNode->pLeft == pTemp){
pNode->pLeft = NULL;
}else{
pNode->pRight = NULL;
}
free(pTemp);
pTemp = NULL;
while(1){
if(pBrother->nColor == RED){
pNode->nColor = RED;
pBrother->nColor = BLACK;
if(pNode->pLeft == pBrother){
RightRotate(&pNode);
pBrother = pNode->pLeft;
continue;
}
if( pNode->pRight == pBrother){
LeftRotate(&pNode);
pBrother = pNode->pRight;
continue;
}
}
if(pBrother->nColor == BLACK){
if((pBrother->pLeft == NULL && pBrother->pRight == NULL)
|| (pBrother->pLeft != NULL && pBrother->pLeft->nColor == BLACK) &&
(pBrother->pRight != NULL && pBrother->pRight->nColor == BLACK)){
if(pNode->nColor == RED){
pNode->nColor = BLACK;
pBrother->nColor = RED;
break;
}
if(pNode->nColor == BLACK){
pBrother->nColor = RED;
if(pNode->pFather == NULL){
break;
}
pNode = pNode->pFather;
pBrother = GetNode(pNode);
continue;
}
}
if( (pBrother->pLeft != NULL && pBrother->pLeft->nColor == RED)
&& (pBrother->pRight == NULL || pBrother->pRight->nColor == BLACK)){
if(pNode->pRight == pBrother){
pBrother->nColor = RED;
pBrother->pLeft->nColor = BLACK;
RightRotate(&pBrother);
pBrother = pNode->pRight;
continue;
}
if(pNode->pLeft == pBrother){
pBrother->nColor = pNode->nColor;
pNode->nColor = BLACK;
pBrother->pLeft->nColor = BLACK;
RightRotate(&pNode);
break;
}
}
if(pBrother->pRight != NULL && pBrother->pRight->nColor == RED){
if(pBrother == pNode->pLeft){
pBrother->nColor = RED;
pBrother->pRight->nColor = BLACK;
LeftRotate(&pBrother);
pBrother = pNode->pLeft;
continue;
}
if(pBrother == pNode->pRight){
pBrother->nColor = pNode->nColor;
pNode->nColor = BLACK;
pBrother->pRight->nColor = BLACK;
LeftRotate(&pNode);
break;
}
}
}
}
}
void RightRotate(RBT **pTree)
{
if(*pTree == NULL || (*pTree)->pLeft == NULL)return;
RBT *pNode = *pTree;
RBT *pMark = pNode->pLeft;
pNode->pLeft = pMark->pRight;
pMark->pRight = pNode;
if(pNode->pFather != NULL){
if(pNode->pFather->pLeft == pNode){
pNode->pFather->pLeft = pMark;
}else{
pNode->pFather->pRight = pMark;
}
}else{
pRBT = pMark;
}
if(pNode->pLeft != NULL){
pNode->pLeft->pFather = pNode;
}
pMark->pFather = pNode->pFather;
pNode->pFather = pMark;
}
void LeftRotate(RBT **pTree)
{
if(*pTree == NULL || (*pTree)->pRight == NULL) return;
RBT *pNode = *pTree;
RBT *pMark = pNode->pRight;
pNode->pRight = pMark->pLeft;
pMark->pLeft = pNode;
if(pNode->pFather != NULL){
if(pNode->pFather->pLeft == pNode){
pNode->pFather->pLeft = pMark;
}else{
pNode->pFather->pRight = pMark;
}
}else{
pRBT = pMark;
}
if(pNode->pRight != NULL){
pNode->pRight->pFather = pNode;
}
pMark->pFather = pNode->pFather;
pNode->pFather = pMark;
}
RBT *FindNode(RBT *pTree, int nNum)
{
if(pTree == NULL)return NULL;
while(pTree != NULL){
if(nNum > pTree->nValue){
if(pTree->pRight == NULL)
return pTree;
pTree = pTree->pRight;
}else if(nNum < pTree->nValue){
if(pTree->pLeft == NULL)
return pTree;
pTree = pTree->pLeft;
}else{
printf("data error.\n");
exit(1);
return NULL;
}
}
return NULL;
}
//得到传入的节点的兄弟
RBT *GetNode(RBT *pTree)
{
if(pTree->pFather->pLeft == pTree){
return pTree->pFather->pRight;
}else{
return pTree->pFather->pLeft;
}
}
void AddNode(int nNum)
{
RBT *pNode, *pMark, *pUncle, *pGrandFather;
RBT *pTree = (RBT *)malloc(sizeof(RBT));
pNode = FindNode(pRBT,nNum);
pTree->nColor = RED;
pTree->nValue = nNum;
pTree->pFather = pNode;
pTree->pLeft = NULL;
pTree->pRight = NULL;
pMark = pTree;
if(pNode == NULL){
pRBT = pMark;
pRBT->nColor = BLACK;
return;
}
if(pNode->nValue > nNum){
pNode->pLeft = pTree;
}else{
pNode->pRight = pTree;
}
if(pNode->nColor == BLACK)
return;
pUncle = NULL;
pGrandFather = NULL;
while(pNode != NULL && pNode->nColor == RED){
pUncle = GetNode(pNode);
pGrandFather = pNode->pFather;
if(pUncle != NULL && pUncle->nColor == RED){
pUncle->nColor = BLACK;
pNode->nColor = BLACK;
pGrandFather->nColor = RED;
pMark = pGrandFather;
if(pMark->pFather == NULL){
pRBT->nColor = BLACK;
return;
}
pNode = pMark->pFather;
continue;
}
if(pUncle == NULL || pUncle->nColor == BLACK){
if(pGrandFather->pLeft == pNode){
if(pNode->pRight == pMark){
pMark = pNode;
LeftRotate(&pMark);
pNode = pMark->pFather;
continue;
}else if(pNode->pLeft == pMark){
pNode->nColor = BLACK;
pGrandFather->nColor = RED;
RightRotate(&pGrandFather);
break;
}
}else if(pGrandFather->pRight == pNode){
if(pNode->pLeft == pMark){
pMark = pNode;
RightRotate(&pMark);
pNode = pMark->pFather;
continue;
}else if(pNode->pRight == pMark){
pNode->nColor = BLACK;
pGrandFather->nColor = RED;
LeftRotate(&pGrandFather);
break;
}
}
}
}
}
void CreateTree(int *arr, int nLength)
{
int i;
if(arr == NULL || nLength <= 0) return;
for(i=0; i<nLength; i++){
AddNode(arr[i]);
}
}
void Traverse(RBT *pTree)
{
if(pTree == NULL) return;
printf("val == %d, col == %d \n",pTree->nValue, pTree->nColor);
Traverse(pTree->pLeft);
Traverse(pTree->pRight);
}
int main()
{
int arr[] = {11,2,14,1,7,15,5,8};
CreateTree(arr,sizeof(arr)/sizeof(arr[0]));
Traverse(pRBT);
printf("_____________________________________\n");
DelNode(pRBT,1);
Traverse(pRBT);
return 0;
}