【C++编程能力提升】

一、235 二叉搜索树的最近公共祖先

题目链接:235 二叉搜索树的最近公共祖先

核心:明确二叉搜索树的性质,即如果某一节点值大于p且小于q,那么该节点即为p和q的最近公共祖先。
(1)若某节点为空,或等于p,或等于q,均直接返回该节点即可;
(2)若某一节点值均大于p和q,说明p和q都在该节点的左子树上,得从左子树遍历确定最近公共祖先;
(3)若某一节点值均小于p和q,说明p和q都在该节点的右子树上,得从右子树遍历确定最近公共祖先。

       TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        //递归法:
        if(!root || root==p || root==q)
            return root;    //node为空则说明不存在公共祖先,node为p或q说明node为公共祖先
        if(root->val > p->val && root->val > q->val)
        {//说明得在左子树遍历寻找
            TreeNode* left=lowestCommonAncestor(root->left,p,q);
            if(left)
                return left;    //left不为空说明已经在左子树遍历过程中找到了公共祖先
        }
        else if(root->val < p->val && root->val < q->val)
        {//说明需要在右子树遍历寻找
            TreeNode* right=lowestCommonAncestor(root->right,p,q);
            if(right)
                return right;
        }
        //root->val >p->val && root->val <q->val,说明root在p、q中间,即返回root
        return root; 
    }

二、701 二叉搜索树中的插入操作

题目链接:701 二叉搜索树中的插入操作

核心:要理解遇到空节点时就进行插入操作
比较待插入元素和根节点值,确定是在左子树插入还是在右子树插入。
最后一行返回root的理解不够深入!

    TreeNode* insertIntoBST(TreeNode* root, int val) {
        //递归法:注意使用二叉搜索树的特性,以及遍历到null时将节点插入,最后返回插入的节点
        if(!root)
        {//root==nullptr,插入节点
            TreeNode* node=new TreeNode(val);
            return node;    //node链接到父节点root上
        }
    //根据二叉搜索树根节点与左子树和右子树的大小关系,确定遍历哪一边,搜索树一定是遍历一条边
        if(root->val > val)
            root->left=insertIntoBST(root->left,val);
        if(root->val < val)
            root->right=insertIntoBST(root->right,val);
        return root;    //为何此处返回root?
    }

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

题目链接:450 删除二叉搜索树中的节点

核心:要理解针对待删除节点的左右孩子的不同情况进行不同操作
(1)待删除节点为空,则无需删除,直接返回该节点;
(2)找到待删除节点了,但需要根据不同的情况进行处理:
第一,待删除节点的左右孩子都为空,直接删除返回空;
第二,待删除节点的左右孩子其一不为空,其一为空,删除该节点后不为空的节点成为根节点,故返回不为空的节点;
第三,待删除节点的左右孩子都不为空(最特别),此时删除节点后,原左孩子需移位到原右孩子的最左边节点,因此先找到待删除节点的右孩子的最左边节点,然后令待删除节点的左孩子移到已找到的最左边节点上,最后删除节点后,原右孩子成为新的根节点。

(3)未找到待删除节点,则需要递归寻找待删除节点,根据二叉搜索树的性质,无需搜索整棵树,只需要搜索一边即可。
最后一行的返回root理解不深?

    TreeNode* deleteNode(TreeNode* root, int key) {
    //递归法:
    //1.当前节点为空,说明没找到要删除的节点
        if(root==nullptr)
            return root;
        if(root->val == key)
        {//已找到要删除的节点
            if(!root->left && !root->right)
            {//2.待删除节点的左右孩子都为空,直接删除该节点返回空即可
                delete root;
                return nullptr;
            }
            else if(root->left && !root->right)
            {//3.待删除节点的左孩子不为空,右孩子为空,那么删除该节点后左孩子成为根节点
                TreeNode* node=root->left;
                delete root;
                return node;
            }
            else if(!root->left && root->right)
            {//4.待删除节点的左孩子为空右孩子不为空,则删除该节点后右孩子成为根节点
                TreeNode* node=root->right;
                delete root;
                return node;
            }
            else
            {//5.待删除节点的左右孩子都不为空,则删除该节点后左孩子需移位到右孩子的最左边节点
                TreeNode* cur=root->right;  //cur寻找待删除节点右孩子的最左边节点
                while(cur->left)
                {//当cur的左孩子为空时退出循环,此时cur即最左边节点
                    cur=cur->left;
                }
                cur->left=root->left;   //待删除节点左孩子移到cur的左孩子处
                TreeNode* tmp=root;
                root=root->right;   //右孩子成为根节点
                delete tmp;
                return root;
            }
        }
        //递归遍历左、右子树,根据二叉搜索树的性质,无需搜索整棵树,只要一条边即可
        if(root->val > key)
            root->left=deleteNode(root->left,key);
        if(root->val < key)
            root->right=deleteNode(root->right,key);
        return root;    //此处返回root不理解?
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值