打卡代码随想录Day10

今天的目标是结束二叉树的学习。

1.二叉搜索树的插入操作(力扣701)

若插入值小于节点值,则插入到左子树,若插入值大于节点值,则插入到右子树,插入的条件为寻找到空时,否则继续用插入值与节点值比较。

class Solution {
    public TreeNode insertIntoBST(TreeNode root, int val) {
        if(root == null)
            return new TreeNode(val);
        else insert(root,val);
        return root;
    }
    public void insert(TreeNode root, int val){
        if(val > root.val && root.right == null){
            root.right = new TreeNode(val);
            return;
        }
        if(val > root.val && root.right != null){
            insert(root.right,val);
        }
        if(val < root.val && root.left == null){
            root.left = new TreeNode(val);
            return;
        }
        if(val < root.val && root.left != null) {
            insert(root.left, val);
        }
    }
}

*2.删除二叉搜索树上的节点(力扣450)

删除节点时分为四种情况讨论:

(1)删除节点无左右孩子时直接删除

(2)删除节点有左孩子没有右孩子时,左孩子直接替换被删除的节点

(3)删除节点没有左孩子有右孩子时,右孩子直接替换被删除的节点

(4)删除节点既有左孩子又有右孩子时,将删除节点的左子树移动到删除节点的右子树的最左侧节点之下,用删除节点的右孩子替换被删除的节点。

class Solution {
    public TreeNode deleteNode(TreeNode root, int key) {
        if(root == null)
            return null;
        if(root.val == key)
        {
            //删除节点无左右孩子,直接删
            if(root.left == null && root.right == null)
                return null;
            //删除节点左孩子不为空,右孩子为空,左孩子直接补位
            if(root.left != null && root.right == null)
                return root.left;
            //删除节点左孩子为空,右孩子不为空,右孩子直接补位
            if(root.left == null && root.right != null)
                return root.right;
            //删除节点左右孩子均不为空时,则将删除节点的左子树放到删除节点的右子树的最左侧节点的左孩子上,返回删除节点右孩子为新的根节点。
            if(root.left != null && root.right != null){
                TreeNode cur = root.right;
                //找到右子树最左侧的节点
                while (cur.left!=null){
                    cur = cur.left;
                }
                cur.left = root.left;
                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;
    }
}

4.修剪二叉搜索树(力扣669)

递归寻找,当不满足区间范围时用满足的节点替换原节点

class Solution {
    public TreeNode trimBST(TreeNode root, int low, int high) {
        if(root == null)
            return null;
        if(root.val < low)
            return trimBST(root.right,low,high);
        if(root.val > high)
            return trimBST(root.left,low,high);
        root.left = trimBST(root.left,low,high);
        root.right = trimBST(root.right,low,high);
        return root;
    }
}

其实无论是删除二叉树上的节点还是搜索二叉树,都需要移除其中的节点,通过递归的方式直接可以跳过需要移除的节点实现移除!

5.将有序数组转换为二叉搜索树(力扣108)

每次将有序数组分为左右两半,根据中间的数构造当前的中间节点,根据数组被分割成的左右两半,递归构造其的左右子树。

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        if(nums.length == 0)
            return null;
        if(nums.length == 1)
            return new TreeNode(nums[0]);
        TreeNode root = new TreeNode(nums[(nums.length-1)/2]);
        root.left = sortedArrayToBST(Arrays.copyOfRange(nums,0,(nums.length-1)/2));
        root.right = sortedArrayToBST(Arrays.copyOfRange(nums,(nums.length-1)/2+1,nums.length));
        return root;
    }
}

6.二叉搜索树转化为累加树(力扣538)

利用反中序遍历,每个节点的值加上前一个的。

class Solution {
    int pre = 0;
    public TreeNode convertBST(TreeNode root) {
        convertBST1(root);
        return root;
    }

//     按反中序遍历,每个节点的数值要加上前一个
    public void convertBST1(TreeNode root) {
        if (root == null) {
            return;
        }
        convertBST1(root.right);
        root.val += pre;
        pre = root.val;
        convertBST1(root.left);
    }
//    public void convertBST2(TreeNode root){
//        if(root == null)
//            return;
//        int pre = 0;
//        Deque<TreeNode> deque = new ArrayDeque<>();
//        while (!deque.isEmpty()||root!=null){
//            if(root!=null)
//            {
//                deque.push(root);
//                root = root.right;
//            }
//            else {
//                root = deque.pop();
//                root.val += pre;
//                pre = root.val;
//                root = root.left;
//            }
//        }
//    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值