二叉树探索篇Ⅴ

Leetcode701——二叉搜索树中的插入操作

题目描述:

给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。

注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回 任意有效的结果 。

示例 1:

输入:root = [4,2,7,1,3], val = 5
输出:[4,2,7,1,3,5]

算法思想:

利用二叉搜索树的特性,当要插入节点的值大于根节点时应该插入右子树中,当插入节点值小于根节点时应该插入左子树当中。递归往下,直至找到该节点应该插入的叶节点位置。

算法实现:

TreeNode* insertIntoBST(TreeNode* root, int val) {
        if(!root) {
            TreeNode* node=new TreeNode(val);
            return node;
        }
        if(root->val>val) root->left=insertIntoBST(root->left,val);
        if(root->val<val) root->right=insertIntoBST(root->right,val);
        return root;
    }

Leetcode450——删除二叉搜索树中的节点

题目描述:

给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。

一般来说,删除节点可分为两个步骤:

  1. 首先找到需要删除的节点;
  2. 如果找到了,删除它。      

算法思想:

利用二叉搜索树的特性,找到要删除的节点。二叉搜索树有多种删除方式,我用到的方法是

算法实现:

TreeNode* deleteNode(TreeNode* root, int key) {
        if(!root) return nullptr;
        if(root->val==key){
            TreeNode* ltree=root->left;
            TreeNode* rtree=root->right;
            //若要删除的节点左子树为空直接用右子树顶上
            if(!ltree){
                root=rtree;
                return root;
            } 
            if(!rtree){
                root=ltree;
                return root;
            } 
            TreeNode* ltreerchild=ltree->right;
            ltree->right=nullptr;
            root=ltree;
            root->right=rtree;
            if(ltreerchild){
                if(!rtree) root->right=ltreerchild;
                while(rtree->left) rtree=rtree->left;
                rtree->left=ltreerchild;
            }
            return root;
        }
        if(root->val>key) root->left=deleteNode(root->left,key);
        if(root->val<key) root->right=deleteNode(root->right,key);
        return root;
    }

Leetcode669——修剪二叉搜索树

题目描述:

给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。

所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。

示例 1:

输入:root = [1,0,2], low = 1, high = 2
输出:[1,null,2]

算法思想:

利用二叉搜索树的特性,当当前遍历节点值大于上限直接抛弃右子树去左子树找符合要求的节点;当当前遍历节点值小于下限直接抛弃左子树去右子树找符合要求的节点。若值符合要求继续检查左右子树。

算法实现:

TreeNode* trimBST(TreeNode* root, int low, int high) {
        if(!root) return nullptr;
        if(root->val>high){
            return trimBST(root->left,low,high);
        }
        if(root->val<low){
            return trimBST(root->right,low,high);
        }
        if(root->left) root->left=trimBST(root->left,low,high);
        if(root->right) root->right=trimBST(root->right,low,high);
        return root;
    }

Leetcode108——将有序数组转换成为二叉搜索树

题目描述:

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 

平衡二叉搜索树。

示例 1:

输入:nums = [-10,-3,0,5,9]
输出:[0,-10,5,null,-3,null,9]

算法思想:

采用递归的思想,以数组的中间节点不断划分左右子树。

算法实现:

TreeNode* buildTree(vector<int>& nums,int l,int r){
        //此为叶节点,直接返回
        if(l==r){
            TreeNode* node=new TreeNode(nums[l]);
            return node;
        }
        //此为空节点
        if(l>r) return nullptr;
        //此为根节点
        int mid=(l+r)/2;
        TreeNode* root=new TreeNode(nums[mid]);
        root->left=buildTree(nums,l,mid-1);
        root->right=buildTree(nums,mid+1,r);
        return root;
    }
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        return buildTree(nums,0,nums.size()-1);
    }

Leetcode538——把二叉搜索树转换为累加树

题目描述:

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

提醒一下,二叉搜索树满足下列约束条件:

  • 节点的左子树仅包含键 小于 节点键的节点。
  • 节点的右子树仅包含键 大于 节点键的节点。
  • 左右子树也必须是二叉搜索树。

    示例 1:

    输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
    输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]

算法思想:

利用二叉搜索树的特性,按照右中左遍历即可得到一个降序序列。通过双指针,在每次遍历节点时,将该节点的值更新为该节点值加上上一个节点的值。

算法实现:

TreeNode* pre=nullptr;
    void alterTree(TreeNode* cur){
        if(!cur) return;
        alterTree(cur->right);
        if(pre!=nullptr) cur->val+=pre->val;
        pre=cur;
        alterTree(cur->left);
        return;
    }
    TreeNode* convertBST(TreeNode* root) {
        alterTree(root);
        return root;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值