手写平衡二叉树(二)

删除数据

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);
}

你可能感兴趣的:(手写平衡二叉树(二))