#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;
// }
//}
二叉树的增删查改和得到父节点
最新推荐文章于 2021-10-10 10:54:35 发布