红黑树的插入C实现

本文详细介绍了红黑树的实现过程,包括左旋、右旋、插入、调整等关键操作,通过随机生成数组并插入红黑树,展示了红黑树在保持平衡的同时高效地进行查找、插入和删除操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
#include  <stdio.h>
#include <time.h>
using namespace std;
#define red 0 
#define black 1
#define SIZE  10
#define MAX 100
typedef struct RB{
   int key;
   int color;
   struct RB  *ptParent;
   struct RB *ptLeft;
   struct RB *ptRight;


}RBT;
void leftRotate(RBT **root,RBT *pX);
void rbFixUp(RBT **root,RBT *pZ);
void rightRotate(RBT **root,RBT *pX);
void rbInsert(RBT **root,RBT *pZ);
void rbPrint(RBT *pX);
void treePrint(RBT **root);
void Random(int *A,int max,int length);

int main(){


	RBT **root;
	root=(RBT**)malloc(sizeof(RBT*));
    *root=NULL;

	int *A;
	A=(int*)malloc(sizeof(int)*SIZE);
    int i ;
    Random(A,MAX,SIZE);
	for(i=0;i<SIZE;i++){
	
	printf("%5d",A[i]);
	}
   puts("\n");

   for(i=0;i<SIZE;i++){
   
     RBT *pZ = (RBT*)malloc(sizeof(RBT));
	 printf("\n Now insert  the  element %d:\n",A[i]);
     pZ->key=A[i];
	 rbInsert(root,pZ);
	 treePrint(root);

	 system("pause");
   
   }
   puts("\nthe total  tree  is :  \n");
   treePrint(root);
   system("pause");

return 0;
}

///左旋
void leftRotate(RBT **root,RBT *pX){
RBT *pY;
pY=pX->ptRight;

if(pX->ptRight != NULL && pY!=NULL)
    pX->ptRight = pY->ptLeft;
if(pY != NULL && pY->ptLeft!= NULL )
    pY->ptLeft->ptParent=pX;
if(pY!=NULL)
  pY->ptParent=pX->ptParent;
if(pX->ptParent==NULL)
    *root=pY;
else{
	if(pX==pX->ptParent->ptLeft)
		pX->ptParent->ptLeft=pY;
	else
	pX->ptParent->ptRight=pY;

}
if(pY!=NULL)
pY->ptLeft = pX;
pX->ptParent=pY;

}
//右旋
void rightRotate(RBT **root,RBT *pX){
RBT *pY;
pY=pX->ptLeft;
if(pX->ptLeft != NULL && pY!=NULL)
   pX->ptLeft = pY->ptRight;
if(pY->ptRight != NULL && pY->ptLeft!= NULL )
    pY->ptRight->ptParent=pX;

pY->ptParent=pX->ptParent;
if(pX->ptParent==NULL)
   *root = pY;
else{
  if(pX==pX->ptParent->ptLeft)
    pX->ptParent->ptLeft=pY;
  else
	  pX->ptParent->ptRight=pY;

}
pY->ptRight=pX;
pX->ptRight=pY;

}
/////红黑树插入
void  rbInsert(RBT **root,RBT *pZ){

	RBT *pY,*pX;
	pY=NULL;
	pX=*root;
	while(pX!=NULL){
	
	pY=pX;
    if(pZ->key<pX->key )
      pX=pX->ptLeft;
	else
		pX=pX->ptRight;
	
	}
  pZ->ptParent=pY;
  if(pY==NULL)
	  *root = pZ;
  else{
     if(pZ->key <pY->key)
		 pY->ptLeft=pZ;
	 else
		 pY->ptRight=pZ;
  
  
  }
  pZ->ptLeft=pZ->ptRight=NULL;
  pZ->color = red;
  rbFixUp(root,pZ);
}
//红黑树调整
void rbFixUp(RBT **root,RBT *pZ){

	if(*root!=NULL){
     RBT *pY;
	while(pZ->ptParent!=NULL && pZ->ptParent->color==red ){
	
		if(pZ->ptParent->ptParent->ptLeft==pZ->ptParent){
		  pY=pZ->ptParent->ptParent->ptRight;///Y 是 Z的叔节点
		  if(pY!=NULL && pY->color == red ){ ////第一种情况
            pZ->ptParent->color=pY->color=black;
			pZ->ptParent->ptParent->color=red;
			pZ=pZ->ptParent->ptParent;


		  }else{ ///第  二三种情况
		  
			  if(pZ==pZ->ptParent->ptParent){
			    pZ=pZ->ptParent;
				leftRotate(root,pZ);
			  
			  }
              pZ->ptParent->color=black;
			  pZ->ptParent->ptParent->color=red;
			  leftRotate(root,pZ->ptParent->ptParent);

		  }
		
		}
	
	}
	(*root)->color=black;
	}
}
///////
void rbPrint(RBT *pX){
	if(pX != NULL){
	
	printf("key:%d \t",pX->key);
	if(pX->color==red)
		printf("color:red\t");
	else
		printf("color:black\t");

	if(pX->ptLeft !=NULL)
	
		printf("left;%d\t",pX->ptLeft->key);
	else
		printf("left:nil\t");

   if(pX->ptRight != NULL)
	   printf("right;%d\t",pX->ptRight->key);
    else
      printf("right:nil \t");
   if(pX->ptParent != NULL)
	   printf("parent: %d \t",pX->ptParent->key);
   else
	   printf("*root\t");
	
	}
	else
		printf("empty");
	    puts("\n");
 
}
/////从根节点开始先序遍历打印树
void  treePrint(RBT **root){
	if(*root != NULL){
		rbPrint(*root);
		treePrint(&((*root)->ptLeft));
		treePrint(&((*root)->ptRight));	
	}
}

////////随机产生数组A
void   Random(int *A,int max,int length ){
  srand(time(NULL));
     int i;
    int c;
    int k = max+1;
	   int *B=(int *)malloc(sizeof(int)*k);
   for(i=0;i<k;i++)
	      B[i]=i;
   for(i=0;i<length;i++){
   c=rand()%k;
   k--;
   A[i]=B[c];B[c]=B[k];

   }

}

end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二十六画生的博客

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值