红黑树插入算法的实现

思想:将插入的节点着色为红色插入红黑树中,然后再调用一个辅助程序对节点重新着色并旋转以保证红黑树的性质得以继续保持。调整程序主要处理为三种情况

CASE1:当前调整节点的叔叔是红色的。

CASE2:当前调整节点的叔叔是黑色的,而且当前调整节点是右孩子。

CASE3:当前调整节点的叔叔是黑色的,而且当前调整节点是左孩子。

结果:随机产生1000个数据,输出红黑树的高度


源码:

head.h:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

enum rb_color {RED,BLACK};

typedef struct node{
	int key;
	struct node * left;
	struct node * right;
	struct node * parent;
	enum rb_color  color;  
}RBNode, *RBTree;


RBTree NIL;
void Init();
RBTree  Creat_Node(RBTree*,int);
void Left_Rotate(RBTree*,RBTree);
void Right_Rotate(RBTree*,RBTree);
void RB_Insert(RBTree*,RBTree);
void RB_Insert_Fixup(RBTree*,RBTree);
void Inorder(RBTree );
void Preorder(RBTree );
int  height(RBTree );


rbtree.c


#include "head.h"

void Init(){
	NIL = (RBTree)malloc(sizeof(RBNode));
	NIL->key = 0;
	NIL->left= NULL;
	NIL->parent = NULL;
	NIL->right = NULL;
	NIL->color = BLACK;
}

RBTree Creat_Node(RBTree *pnode,int key){
	if(((*pnode) = (RBTree)malloc(sizeof(RBNode)))!=NULL){
		(*pnode)->key = key;
		(*pnode)->left = NIL;
		(*pnode)->right = NIL;
		(*pnode)->parent = NIL;
		(*pnode)->color = RED;
		return *pnode;
	}
	else return NULL;
}


void Left_Rotate(RBTree * T,RBTree pnode){
	
	RBTree temp = pnode->right;
	pnode->right = temp->left;
	if(temp->left!=NIL)
		temp->left->parent = pnode;
	temp->parent = pnode->parent;
	if(pnode->parent==NIL)
		*T = temp;
	else if(pnode->parent->left==pnode)
		pnode->parent->left = temp;
	else
		pnode->parent->right = temp;
	temp->left = pnode;
	pnode->parent = temp;
}


void Right_Rotate(RBTree * T,RBTree pnode){
	
	RBTree temp = pnode->left;
	pnode->left = temp->right;
	if(temp->right!=NIL)
		temp->right->parent = pnode;
	temp->parent = pnode->parent;
	if(pnode->parent==NIL)
		*T = temp;
	else if(pnode->parent->left==pnode)
		pnode->parent->left = temp;
	else
		pnode->parent->right = temp;
	temp->right = pnode;
	pnode->parent = temp;

}


void RB_Insert(RBTree *T,RBTree pnode){
	
	RBTree ptemp = *T,qtemp = NIL;
	//if(pnode==NULL) {printf("pnode is null\n");return;}
	while(ptemp!=NIL){
		qtemp = ptemp;
		if(pnode->key < ptemp->key)
			ptemp = ptemp->left;
		else
			ptemp = ptemp->right;
	}
	pnode->parent = qtemp;
	if(qtemp == NIL)
		*T = pnode;
	else if (pnode->key > qtemp->key)
		qtemp->right = pnode;
	else
		qtemp->left = pnode;
	pnode->left = NIL;
	pnode->right = NIL;
	pnode->color = RED;
	RB_Insert_Fixup(T,pnode);
}


void RB_Insert_Fixup(RBTree* T,RBTree pnode){
	
	RBTree ptemp = NULL;
	while(pnode->parent->color==RED){

		if(pnode->parent==pnode->parent->parent->left){
			ptemp = pnode->parent->parent->right;
			if(ptemp->color==RED){
				pnode->parent->color = BLACK;
				pnode->parent->parent->color = RED;
				ptemp->color = BLACK;
				pnode = pnode->parent ->parent ;
			}
			else{
				if(pnode->parent->right==pnode){  //case2:
					pnode = pnode->parent ;
					Left_Rotate(T,pnode);
				}
				pnode->parent->color = BLACK;
				pnode->parent->parent->color = RED; 
				Right_Rotate(T,pnode->parent->parent);
			}
		}//if
		else{
			ptemp = pnode->parent->parent->left;
			if(ptemp->color==RED){
				pnode->parent->color = BLACK;
				pnode->parent->parent->color = RED;
				ptemp->color = BLACK;
				pnode = pnode->parent ->parent ;
			}
			else{
				if(pnode->parent->left==pnode){  //case2:
					pnode = pnode->parent ;
					Right_Rotate(T,pnode);
				}
				pnode->parent->color = BLACK;
				pnode->parent->parent->color = RED; 
				Left_Rotate(T,pnode->parent->parent);
			}
		}//else
	}//while
	(*T)->color = BLACK;
}


void Inorder(RBTree T){
	if(T!=NIL){
		Inorder(T->left);
	    printf("key:%d \tcolor:%s\n",T->key,T->color?"BLACK":"RED");
		Inorder(T->right);
	}
}

void Preorder(RBTree T){
	if(T!=NIL){
	    printf("key:%d \tcolor:%s\n",T->key,T->color?"BLACK":"RED");
		Preorder(T->left);
		Preorder(T->right);
	}
}

int  height(RBTree T){
	
	int left,right;
	if(T==NIL) return 0;
	left = height(T->left);
	right = height(T->right);
	return left>right?left+1:right+1;
}

main.c:

#include"head.h"

int main(){
	RBTree T ,pnode;
	int i,k;
	Init();
	T = NIL;
	pnode = NULL;
	srand((unsigned)time(NULL));
	for(i = 0;i<1000;i++){
		k=rand() % 5000;
		if(Creat_Node(&pnode,k)==NULL){
			printf("fail to creat node...\n");
			exit(1);
		}
		RB_Insert(&T,pnode);
	}
	printf("InOrder:\n");
	Inorder(T);
	printf("\nPreOrder:\n");
	Preorder(T);
	printf("\nheight:%d",height(T));
}





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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值