Leetcode第450 删除二叉搜索树中的节点 C++解法

删除结点的话,假设找到的结点为X;需要处理X和父节点之间的关系,我之前直接删除叶子结点就是这里错了,直接删除造成内存泄露。
用递归去做的话,这个结点本身是叶子结点或单边结点,那么在递归的返回值可以解决这个问题,直接返回null或另一边地址即可。
但如果是左右结点都在,有两种操作方式,(我们这里都去找该结点的后继结点Y,也就是该结点的右孩子的最左孩子)
第一种,让X的左结点挂到原来Y的左结点上,同时返回X的右节点即可;这种操作会使树的高度j加倍,如果不是AVL树的话无所谓。而实际上AVL树采用的是下面第二种方式。
第二种,用Y的值去替代X的值,同时将问题转化为删除Y。
递归去做

class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key)
    {
        if(root==nullptr)
        return nullptr;
        if(root->val==key)
        {
            if(root->left&&root->right)
            {
                TreeNode *pre=root;
                TreeNode *pmove=root->right;
                while(pmove->left)
                    {pre=pmove;
                    pmove=pmove->left;}
                root->val=pmove->val;
                /*下面我就是没有考虑到父结点的情况下删除叶子结点造成泄漏
                 if(pmove->right)
                 {
                     TreeNode *temp=pmove;
                     pmove=pmove->right;
                     temp->val=pmove->val;
                     temp->left=pmove->left;
                    temp->right=pmove->right;
                 }
                 delete pmove;
                 pmove=NULL;
                 */
                if(pre->right==pmove)
                root->right=pmove->right;
                else
                    pre->left=pmove->right;
                delete pmove;
                pmove=NULL;
                /*上面五行也可以用下面的一句递归调用来解决,也不用pre变量,能大大减少代码长度
                 root->right=deleteNode(root->right,pmove->val);
                */
                return root;               
            }
            else if(root->left)
            return root->left;
            else
            return root->right;
        }
        if(root->val>key)   root->left=deleteNode(root->left,key);
        if(root->val<key)   root->right=deleteNode(root->right,key);
        return root;
    }
};

迭代来做

class Solution {
public:
    void ifroot(TreeNode* pmove,TreeNode* pre)
    {
        if(pmove->right&&pmove->left)
        {
            TreeNode* prl=pmove->right;
            pre=pmove;
            while(prl->left)
            {pre=prl;
            prl=prl->left;}
            pmove->val=prl->val;
            if(pre->right==prl)
            pre->right=prl->right;
            else
            pre->left=prl->right;
            delete prl;
            pre==NULL;            
        }
        else if(pmove->left)
        {
            if(pmove==pre->left)
                pre->left=pmove->left;
            else
                pre->right=pmove->left;
            pmove=NULL;
        }
        else
        {
            if(pmove==pre->left)
                pre->left=pmove->right;
            else
                pre->right=pmove->right;
            pmove=NULL;
        }
    }
    TreeNode* deleteNode(TreeNode* root, int key) {
        TreeNode *pmove=root;
        TreeNode *pre=new TreeNode(0,root,NULL);
        while(pmove&&pmove->val!=key)
            {pre=pmove;
            pmove=pmove->val>key?pmove->left:pmove->right;}
        if(!pmove)  return root;
        ifroot(pmove,pre);
        if(root==pmove)
            root=pre->left;
        return root;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值