红黑二叉查找树的插入

无奈,书上所说的删除还没能领悟,以后补上吧

//RBTree.h

#ifndef _RBTREE_H_
#define _RBTREE_H_

#include <stdlib.h>

typedef int Element;
typedef enum
{
	RED,
	BLACK
}Color;

typedef struct _RBT_Node_
{
	Color NodeColor;
	Element data;
	struct _RBT_Node_ *Parent;
	struct _RBT_Node_ *LeftChild;
	struct _RBT_Node_ *RightChild;
}RBT_Node;

typedef RBT_Node* RBT;

void InitRBT(RBT *tree);
RBT_Node* CreateNode(Element v, Color NodeColor);
bool InsertRBT(RBT *tree, Element v);
void RotateL(RBT *tree);
void RotateR(RBT *tree);
void TransColors(RBT *tree);
bool IsRed(RBT_Node *node);
//bool DeleteRBT(RBT *tree, Element v);

#endif //_RBTREE_H_

//RBTree.cpp

#include "RBTree.h"

void InitRBT(RBT *tree)
{
	*tree = NULL;
}

RBT_Node* CreateNode(Element v, Color NodeColor)
{
	RBT_Node *p = (RBT_Node *)malloc(sizeof(RBT_Node));
	if( NULL == p )
		return NULL;

	p->data = v;
	p->LeftChild = NULL;
	p->RightChild = NULL;
	p->Parent = NULL;
	p->NodeColor = NodeColor;
}

bool InsertRBT(RBT *tree, Element v)
{
	RBT_Node *q = *tree;
	RBT_Node *p = NULL;
	RBT_Node *s = NULL;

	if( NULL == *tree )					//根节点为黑节点
	{
		*tree = CreateNode(v, BLACK);
		if( NULL == *tree )
			return false;
	}
	else
	{
		while ( NULL != q)	//寻找插入位置
		{
			p = q;			//记录路径
			if( q->data > v )
				q = q->LeftChild;
			else if( q->data < v )
				q = q->RightChild;
			else
				return false;
		}

		q = CreateNode(v, RED);
		if( NULL == q )
			return false;

		 if( p->data > v )			//连接新节点
			 p->LeftChild = q;
		 else
			 p->RightChild = q;

		 q->Parent = p;

		 while (NULL != p)			//从新节点的父节点开始向上回溯,准备调整各种不符合定义的红链接,因为红色存在上传的可能,所以需要尽可能回溯
		 {
			 s = p->Parent;
			if( !IsRed(p->LeftChild) && IsRed(p->RightChild) )				//仅右孩子是红
				RotateL(&p);
			if( IsRed(p->LeftChild) && IsRed(p->LeftChild->LeftChild) )		//左孩子即左孙子都红,短路法则保证不会对NULL进行->操作
				RotateR(&p);
			if( IsRed(p->LeftChild) && IsRed(p->RightChild) )				//左右孩子都红
				TransColors(&p);

			if( NULL == s )		//旋转函数前p为整棵树的根,修改新根
				*tree = p;
			p = p->Parent;		//回溯
		 }
	}

}

bool IsRed(RBT_Node *node)
{
	if( NULL == node )
		return false;

	return RED == node->NodeColor;
}

void TransColors(RBT *tree)
{
	if( NULL == (*tree)->Parent )
		(*tree)->NodeColor = BLACK;		//树根必须为黑
	else
		(*tree)->NodeColor = RED;		
	(*tree)->LeftChild->NodeColor = BLACK;
	(*tree)->RightChild->NodeColor = BLACK;
}

void RotateL(RBT *tree)				//左旋转
{
	RBT_Node *pp = (*tree)->Parent;
	RBT_Node *p = (*tree)->RightChild;
	RBT_Node *c = *tree;

	c->RightChild = p->LeftChild;		//保存p可能出现的左孩子
	if( NULL != p->LeftChild )
		p->LeftChild->Parent = c;
	p->LeftChild = c;					//旋转
	c->Parent = p;
	p->NodeColor = c->NodeColor;		//交换节点颜色
	c->NodeColor = RED;

	if( NULL != pp && pp->LeftChild == c )	//重新连接到外部
		pp->LeftChild = p;
	if( NULL != pp && pp->RightChild == c )
		pp->RightChild = p;

	p->Parent = pp;							
	*tree = p;
}

void RotateR(RBT *tree)
{
	RBT_Node *pp = (*tree)->Parent;
	RBT_Node *p = (*tree)->LeftChild;
	RBT_Node *c = *tree;

	c->LeftChild = p->RightChild;
	if( NULL != p->RightChild )
		p->RightChild->Parent = c;
	p->RightChild = c;
	c->Parent = p;
	p->NodeColor = c->NodeColor;
	c->NodeColor = RED;

	if( pp != NULL && pp->LeftChild == c )
		pp->LeftChild = p;
	if (pp != NULL && pp->RightChild == c)
		pp->RightChild = p;

	p->Parent = pp;
	*tree = p;
}

/*
bool DeleteRBT(RBT *tree, Element v)
{
	RBT_Node *q = *tree;
	RBT_Node *p = NULL;
	while (NULL != q)		//寻找
	{
		if( v == q->data )
			break;
		else if( v > q->data )
			q = q->RightChild;
		else
			q = q->LeftChild;
	}

	if( NULL == q )		//根为空或节点不存在
		return false;

	if( NULL != q->LeftChild && NULL != q->RightChild )	//存在左右孩子,转化为只有一个孩子的情况
	{
		p = q->RightChild;
		while (NULL != p->LeftChild)		//寻找右子树中最小节点
			p = p->LeftChild;

		q->data = p->data;					//替换
		q = p;
	}

	
	
}
*/

//main.cpp

#include <stdio.h>
#include  <stdlib.h>
#include "RBTree.h"

int main(int argc, char **argv)
{
	RBT tree;
//	Element Array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
	Element Array[] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
	int num = sizeof(Array) / sizeof(Element);

	InitRBT(&tree);
	for(int i= 0; i < num; i++)
		InsertRBT(&tree, Array[i]);
	system("pause");
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值