二叉树的增删查改和得到父节点

#include<stdio.h>
#include<malloc.h>
typedef struct Tree {
	int data;
	Tree *Lp, *Rp;
}Tree;
//得到父节点
Tree* GetFather(Tree*p, int data)
{
	if (p == NULL) { return false; }
	if (p->Lp == NULL&&p->Rp == NULL) { return false; }
	if (p->Lp != NULL) 
	{
		if(p->Lp->data==data)
		{
			return p;
		}
	}
	if (p->Rp != NULL)
	{
		if (p->Rp->data == data)
		{
			return p;
		}
	}
	if (p->data > data) { return GetFather(p->Lp, data); }
	if (p->data < data) { return GetFather(p->Rp, data); }
}
bool DeleteTree(Tree*&p)
{//在c++操作符重载时 || && 是没有办法实现短路规则的 所以不要重载 但是是可以重载的
//注意这里使用引用 避免悬空指针
	if (p == NULL) { return false; }
	if (p->Lp != NULL&&p->Rp != NULL) { DeleteTree(p->Lp); DeleteTree(p->Rp); }
	if (p->Lp != NULL&&p->Rp == NULL) {  DeleteTree(p->Lp); }
	if (p->Lp == NULL&&p->Rp != NULL) {  DeleteTree(p->Rp); }
	if (p->Lp == NULL&&p->Rp == NULL) { free(p);p = NULL;return true; }
}
//删除 主要依赖于  GetFather()函数
bool DeleteData(Tree*p, int data)`在这里插入代码片`
{
	Tree* TT = NULL;
	Tree* temp = GetFather(p, data);
	if (temp==NULL) { return false; }
	else
	{//temp 为父节点 但不知道 需要删除的节点是父节点的左节点还是右节点 
	 //所以这里需要讨论
		if(temp->Lp!=NULL&&temp->Lp->data==data)
	{
		//情况一
		if(temp->Lp->Lp==NULL&&temp->Lp->Rp==NULL)
		{
			free(temp->Lp);
			temp->Lp = NULL;
			return true;
		}
        //情况二		
		if (temp->Lp->Lp != NULL&&temp->Lp->Rp == NULL) {
			TT= temp->Lp->Lp;
			free(temp->Lp);temp->Lp = TT;
			return true;
		}
		//情况三
		if (temp->Lp->Lp == NULL&&temp->Lp->Rp != NULL) 
		{
			 TT= temp->Lp->Rp;
			 free(temp->Lp);temp->Lp = TT;
			 return true;
		}
		//情况四
		if (temp->Lp->Lp != NULL&&temp->Lp->Rp != NULL) 
		 {//这种情况 是要看具体的要求了 在这里不在讨论 我在这里不做处理
			  return false;
		 } 
  } 
		//temp 为父节点 但不知道 需要删除的节点是父节点的左节点还是右节点 
		//所以这里需要讨论
		if (temp->Rp != NULL&&temp->Rp->data == data)
		{
			//情况一
			if (temp->Rp->Lp == NULL&&temp->Rp->Rp == NULL)
			{
				free(temp->Rp);
				temp->Rp = NULL;
				return true;
			}
			//情况二
			if (temp->Rp->Lp != NULL&&temp->Rp->Rp == NULL)
			{
				TT = temp->Rp->Lp;
				free(temp->Rp);
				temp->Rp = TT;
				return true;
			}
			//情况三
			if (temp->Rp->Lp == NULL&&temp->Rp->Rp != NULL)
			{
				TT = temp->Rp->Rp;
				free(temp->Rp);
				temp->Rp = TT;
				return true;
			}
			//情况四
			if (temp->Rp->Lp != NULL&&temp->Rp->Rp != NULL)
			{//这种情况 是要看具体的要求了 在这里不在讨论 我在这里不做处理
				return false;
			}
		}
	}
}
//创造
Tree* CreateTree(int data)
{
	Tree* temp = (Tree*)malloc(sizeof(Tree));
	temp->data = data;
	temp->Rp = NULL;
	temp->Lp = NULL;
	return temp;
}
//增加   这里的插入不能保证节点的唯一性    所以我在下面在补充一下
// 能保证节点唯一性的代码和InsertTree()函数通用
bool InsertTree(Tree**p, int data)
{
	if (!(*p))
	{
		Tree*temp = (Tree*)malloc(sizeof(Tree));
		temp->data = data;temp->Lp = NULL;temp->Rp = NULL;
		*p = temp;
		return true;
	}
	else if ((*p)->data>data)
	{
		return  InsertTree(&((*p)->Lp), data);
	}
	else if ((*p)->data<data) {
		return InsertTree(&((*p)->Rp), data);
	}
}
//查找  这里返回值是p指针
Tree* `IsFind(Tree*p, int data)`
{
	if (p == NULL) { return nullptr; }
	else if (p->data == data) { return p; }
	else if (p->data > data) { return IsFind(p->Lp, data); }
	else if (p->data < data) { return IsFind(p->Rp, data); }
}
//改变
bool ChangeData(Tree*p, int data, int ChangeData)
{
	Tree*temp = NULL;
	if (temp = IsFind(p, data)) { temp->data = ChangeData;return true; }
	return false;
}
//显示 前序遍历 打印
void show(Tree* p)
{
		if (p == 0) {
			return;
		}
		printf("%d  ", p->data);
		show(p->Lp);
		show(p->Rp);
}
	int main()
	{
		Tree*p = CreateTree(5);
		
		InsertTree(&p, 4);
		InsertTree(&p, 3);
		InsertTree(&p, 9);
		InsertTree(&p, 10);
		InsertTree(&p, 11);
		InsertTree(&p, 12);
		InsertTree(&p, 13);
		InsertTree(&p, 14);
		InsertTree(&p, 15);
		InsertTree(&p, 16);

		//得到父节点 测试
		Tree*pp=GetFather(p, 1);
		if(pp!=NULL)
		{
			pp->data = 10;
		}
		else
		{
			printf("的到父节点失败\n");
		}

		//查找函数测试
		if (IsFind(p, 8)) { printf("Find\n"); }
		else
		{
			printf("No Find\n");
		}
	
		//改变函数测试
		printf("改变函数测试\n");
		ChangeData(p, 3, 100);
		
		//删除函数
		printf("删除函数测试\n");
		DeleteData(p, 9);
		
		//打印函数
		printf("打印函数测试\n");
		show(p);
	}



//这是保证节点唯一性的代码
//bool InsertNode(Tree*&p, int data)
//{//对指针的引用
//	if (p == NULL) { return false; }
//	if (p->data == data) { return false; }
//	if(p->Lp!=NULL&&p->Rp!=NULL)
//	{//当两个节点都是非空 所以要进行递归
//		if (p->data > data) { return InsertNode(p->Lp, data); }
//		if (p->data < data) { return InsertNode(p->Rp, data); }
//	}
//	if (p->Lp != NULL&&p->Rp == NULL)
//	{
//		if(p->data<data)
//		{//需要先判断大小 不满足 继续递归找
//			Tree*temp = (Tree*)malloc(sizeof(Tree));
//			temp->Lp = NULL;temp->Rp = NULL;temp->data = data;
//			p->Rp = temp;
//			return true;
//		}
//		else
//		{
//			return InsertNode(p->Lp, data);
//		}
//	}
//	if (p->Lp == NULL&&p->Rp != NULL)
//	{
//		if(p->data>data)
//		{//需要先判断大小 不满足 继续递归找
//			Tree*temp = (Tree*)malloc(sizeof(Tree));
//			temp->Lp = NULL;temp->Rp = NULL;temp->data = data;
//			p->Lp = temp;
//			return true;
//		}
//		else {
//			return InsertNode(p->Rp, data);
//		}
//	}
//	if (p->Lp == NULL&&p->Rp == NULL) 
//	{//当两个节点是空 所以需要判断大小后在决定挂在那个节点上
//		Tree*temp = (Tree*)malloc(sizeof(Tree));
//		temp->Lp = NULL;temp->Rp = NULL;temp->data = data;
//		if (p->data > data) { p->Lp = temp; }
//		else
//		{
//			p->Rp = temp;
//		}
//		return true;
//	}
//}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值