非递归法!力扣450:删除二叉搜索树/BST/二叉排序树/二叉查找树的结点

 由于二叉搜索树的特性,非递归法不需要额外模拟栈,但是注意,删除结点时必须知道其父结点、以及所删除的结点是父结点的左孩子还是右孩子!

class Solution {
public:
    TreeNode* deleteOneNode(TreeNode* cur){
        TreeNode* temp=cur;                     //当前结点暂存,最后释放堆区内存
        if(!cur->left && !cur->right){          //叶子结点,直接删除
            cur=nullptr;
        }
        else{
            if(cur->left && !cur->right){       //左孩子非空,右孩子空
                cur=cur->left;
            }
            else if(!cur->left && cur->right){  //右孩子非空,左孩子空
                cur=cur->right;
            }
            else{                               //左右孩子均非空,则把左孩子作为右孩子最左最底层的结点的左孩子
                //寻找右孩子中最左最底结点
                TreeNode* p=cur->right;         //当前结点
                TreeNode* q=nullptr;            //当前结点的父结点
                while(p){
                    q=p;
                    p=p->left;
                }
                q->left=cur->left;
                cur=cur->right;
            }
        }
        delete temp;
        return cur;
    }

    TreeNode* deleteNode(TreeNode* root, int key) {
        TreeNode* cur=root;           //当前指针
        TreeNode* pre=nullptr;        //父结点指针
        
        while(cur){
            int nodeVal=cur->val;
            if(nodeVal==key){           //删除当前结点(注意,删除最顶端结点与其他结点不一样!!)
                if(pre==nullptr){               //删除的结点就是最顶端结点
                    root=deleteOneNode(cur);        
                }
                else{                           //其他结点,判断删除的结点是父结点的左孩子?还是右孩子?
                    if(pre->left && nodeVal==pre->left->val){//要删除的结点是父结点的左孩子
                        pre->left=deleteOneNode(cur);
                    }
                    else if(pre->right && nodeVal==pre->right->val){
                        pre->right=deleteOneNode(cur);
                    }
                }
                break;
            }
            else{                       //非当前结点,需要更新父结点为当前结点,再去看左右孩子
                pre=cur;
                if(nodeVal< key)    cur=cur->right;
                else    cur=cur->left;
            }
        }
        return root;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值