450.删除二叉搜索树中的节点

解题思路

逻辑:首先找到要删除的结点;找到后分情况讨论:
(1)左右孩子都为空,直接删除结点(delete node)
(2)左孩子为空,右孩子不为空,删除结点,右孩子补位
(3)右孩子为空,左孩子不为空,删除结点,左孩子补位
(4)左右孩子都不为空,就将左孩子连接到右孩子最左边的叶子结点上,然后删除结点,将右孩子补位

1、递归法:
(1)确定递归终止条件:当本次递归没找到要删除的结点时,返回空
(2)单层递归逻辑:根据要找的结点值与当前传入递归结点进行比较,确定搜索方向。注意用root->left root->right来承接递归返回值。当递归找到要删除的结点后,根据上述4个情况,返回相应的结点。
(3)返回值:root根结点

class Solution {
public:
    TreeNode* deleteNode(TreeNode* root, int key) {
        if(!root)return nullptr;//遇到空结点,说明没有找到要删除的结点,则返回空       
        if(root->val == key ){
            //1、找到了删除结点,其左右孩子均为空
            if(!root->left && !root->right) {
                delete root;
                return nullptr;
            }
            //2、找到了删除结点,其左孩子为空,右孩子不为空
            else if(!root->left){
                TreeNode* cur=root->right;
                delete root;
                return cur;

            }
            //2、找到了删除结点,其右孩子为空,左孩子不为空
            else if(!root->right){
                TreeNode*cur=root->left;
                delete root;
                return cur;
                }
            //1、找到了删除结点,其左右孩子均不为空
            else{               
                TreeNode* rightnode=root->right;
                TreeNode* cur=rightnode;
                while(rightnode->left){
                    rightnode=rightnode->left;
                }
                rightnode->left=root->left;
                delete root;
                return cur;
            }
        }
        if(root->val>key)root->left=deleteNode(root->left,key);
        if(root->val<key)root->right=deleteNode(root->right,key);
        return root;

    }
};

2、迭代法
利用双指针思想,cur指向要删除点,pre指向要删除点的父结点。

class Solution {
public:
//删除结点的函数
    TreeNode* deleteOneNode(TreeNode* node){
        if(!node)return nullptr;
        if(!node->right)return node->left;
        TreeNode* p=node->right;
        TreeNode* tmp=node;
        while(p->left){
            p=p->left;
        }
        p->left=node->left;
        node=node->right;
        delete tmp;
        return node;
    }
    TreeNode* deleteNode(TreeNode* root, int key) {
        //迭代法
        if(!root)return nullptr;
        TreeNode* cur=root;
        TreeNode* pre=nullptr;
		//找到要删除的结点
        while(cur){
            if(cur->val == key)break;
            pre=cur;//更新pre
            if(cur->val > key)cur=cur->left;
            else if(cur->val < key)cur=cur->right;
        }
        //如果pre为空,说明指针没动,根结点就是要删除的点
        if(pre==nullptr)return deleteOneNode(cur);
        //根据二叉搜索树的特点确定搜索方向
        if(pre->left && pre->left->val == key){
            pre->left=deleteOneNode(cur);
        }
        if(pre->right && pre->right->val == key){
            pre->right=deleteOneNode(cur);
        }
        return root;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值