手写平衡二叉树(二)

删除数据

struct Person* removes(struct Person* p,struct Person*data,int(*compare)(struct Person* p1,struct Person* p2))
{
//判断参数是否为空,为空返回传入的参数
	if (NULL == p)
	{
		return p;
	}
	if (NULL == data)
	{
		return p;
		}
//判断当前节点和要删除节点的大小
	int m = compare(p, data);
	//如果小了把当前节点的右节点传入此函数
	if (m<0)
	{
		p->rchild=removes(p->rchild,data,compare);
		return p;
	}else
	//如果大了把当前节点的左节点传入此函数
	if (m > 0)
	{
		p->lchild= removes(p->lchild, data, compare);
		return p;
	}else
	//如果相等进行删除操作
	if (m == 0)
	{//记录父节点
		struct Person* myPrient = p->parent;
		//如果当前节点的左子节点为空
		if (NULL == p->lchild)
		{

		//如果当前节点的右子节点不为空,修改此右子节点的父指向为记录的父节点
			if (p->rchild)
			{
				p->rchild->parent = myPrient;
			}
			//返回此节点的右节点
			return p->rchild;
		}
		//如果当前节点的右子节点为空
		if (NULL == p->rchild)
		{
	//如果当前节点的左子节点不为空,修改此左子节点的父指向为记录的父节点
			if (p->lchild)
			{
				p->lchild->parent = myPrient;
			}
		//返回此节点的左节点
			return p->lchild;
		}
		//如果都不为空,比较左右子节点的高度
		int l = getHight(p->lchild);
		int r = getHight(p->rchild);
		//定义一个指针变量
		struct Person* pCurror;
		//如果左节点大于等于右节点
		if (l >= r)
		{//把左子字节点赋值给定义的变量
			 pCurror = p->lchild;
			 如果指针指向节点的右节点为空
			 if (NULL == pCurror->rchild)
			 {
			//修改左子节点的父指向
				 pCurror->parent = myPrient;
				 //修改左子节点的右子节点指向为节点的右指向
				 pCurror->rchild = p->rchild;
				 //修改左子节点的右子节点的父指向
				 pCurror->rchild->parent = pCurror;
				 //返回修改后的右子节点
				 return pCurror;
				 }	
				 //如果右子节点不为null,循环,直到为空(取左节点的最大值)
			 while (pCurror->rchild)
			 {
				 pCurror = pCurror->rchild;
			 }
		
		
		//把最大值节点父指向赋值给要删除的节点
			 p->parent = pCurror->parent;
			 //修改最大值的父指向
			 pCurror->parent = myPrient;
			 //记录最大值的左子指向
			 struct Person* oldpc = pCurror->lchild;
			 //修改最大值的右子节点指向,并修改右子节点的父指向
			 pCurror->rchild = p->rchild;
			 pCurror->rchild->parent = pCurror;
			 //修改最大值的左子节点指向,并修改左子节点的父指向
			 pCurror->lchild = p->lchild;
			 pCurror->lchild->parent = pCurror;
			// 修改删除值得父指向得右子指向为记录得左指向
			 p->parent->rchild = oldpc;
			 //如果不为空,修改父指向
			 if (oldpc)
			 {
				 oldpc->parent = p->parent;
			 }
			 //返回修改后的节点
			 return pCurror;

			 }
		else {
		//记录节点的右子节点
			pCurror = p->rchild;
			//判断右子节点的左节点是否为空
			if (NULL == pCurror->lchild)
			{
		
//为空,修改右子节点的父节点为节点的父节点
				pCurror->parent = myPrient;
				//修改左子节点的左节点为节点的左子节点
				pCurror->lchild = p->lchild;
				//修改左子节点的父指向
				pCurror->lchild->parent = pCurror;
				//返回修改后的左子节点
				return pCurror;
			}
//取右节点的最小值
			while (pCurror->lchild)
			{
				pCurror = pCurror->lchild;
			}
		
			//把最小值节点父指向赋值给要删除的节点
			p->parent = pCurror->parent;
			//修改最小值的父指向
			pCurror->parent = myPrient;
			//记录最小值的右子指向
			struct Person* newrr = pCurror->rchild;
			 //修改最小值的左子节点指向,并修改左子节点的父指向
			pCurror->rchild = p->rchild;
			pCurror->rchild->parent = pCurror;
			//修改最小值的左子节点指向,并修改左子节点的父指向
			pCurror->lchild = p->lchild;
			pCurror->lchild->parent = pCurror;
// 修改删除值得父指向得左子指向为记录得左指向
			p->parent->lchild = newrr;
			 //如果不为空,修改父指向
			if (newrr)
			{
				newrr->parent = p->parent;
			}
       //返回修改后的节点
			return pCurror;
		}
	
		}
	//返回节点
		return p;
		}
	
		

	


void removes_tree(struct ABLtree* tree,struct Person* data,int(*compare)(struct Person* d1,struct Person* d2))
{
//判断参数是否为空
	if (NULL == tree)
	{
		return;
	}
	if (NULL == data)
	{
		return;
	}
	if (NULL == compare)
	{
		return;
	}
	//调用删除函数
	mytree->root=removes(tree->root, data, compare);
	//调用平衡函数
	mytree->root=Adjtree(tree->root);
}

遍历数据

//递归遍历
void myprint(struct Person* p)
{//如果为空返回
	if (!p)
	{
		return;
	}
	//先左后中再右遍历
	myprint(p->lchild);
	printf("%d \n", p->m);
	myprint(p->rchild);
}

void foregr(struct ABLtree* tree,void(*myprint)(struct Person* p))
{//如果为空返回
	if (!tree)
	{
		return;
	}
	//调用打印函数
	myprint(tree->root);
}

销毁

//如果开辟出来的空间不为空,释放空间
if(tree)
{
free(tree);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值