红黑树思维导图-修改了一些没看到的错误-更新了添加和删除的详细解释-代码分析

在这里插入图片描述

//等我后续复习红黑树会画出所涉及到的情况,具体说一下这是如何来的,其实简单来说就一直寻找最简单的情况进行分析。
#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;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值