手写平衡二叉树(二)
点击蓝字之后,我们就是好朋友了啦
删除数据
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);
}
遇见最美的你