二叉查找树节点的删除

简介

本文将介绍如何从二叉查找树中删除某个任意的节点。由于二叉树特有的结构,即:
(1)所有左子树中的节点小于等于根节点
(2)所有右子树中的节点大于等于根节点
(3)对于任意节点满足(1)(2)

所以二叉查找树节点删除关键在于如何保证不破坏二叉查找树的性质。

问题分析

二叉查找树删除节点可以分成三种情况:
(1)删除叶子节点
叶子节点删除是最简单的情况,由于叶子节点没有左右子树,删除后不会破坏原有的树形结构,所以我们只需要找到节点并且把它置为null即可。

如图:
这里写图片描述

(2)被删除的节点只有一个子节点
比如我们要删除上图中3所在的节点,3只有一个左子树1。
实际上我们只需要把5所在节点的左子树指向原来3的左子树即可。

如图:

这里写图片描述

(3)被删除的节点左右子树都有
这种情况是比较复杂的,为了不破坏二叉查找书的结构,我们可以按照以下操作进行:

  • 找出左子树中最大或者右子树中最小的值val
  • 将当前节点的值替换为val
  • 在左子树或者右子树中找到val删除

    Note:
    由于二叉查找树的性质,如果将当前节点替换为左子树中最大的或者右子树中最小的一定不会破坏二叉查找树的结构。

如图:

这里写图片描述

代码

public TreeNode deleteNode(TreeNode root, int key) {

         if(root == null){
             return root;
         }
         if(key < root.val){
             root.left = deleteNode(root.left, key);
             return root;
         }
         if(key > root.val){
             root.right = deleteNode(root.right, key);
             return root;
         }
         //开始执行删除操作
         //(1)删除根节点
         if(root.left == null && root.right == null){
             root = null;
             return root;
         }
         //(2)只有一个child,只有左子树
         if(root.left == null && root.right != null){
             root = root.right;
             return root;
         }
         //(2)只有一个child,只有右子树
         if(root.right == null && root.left != null){
             root = root.left;
             return root;
         }
         //(3)有两个child
         if(root.left != null && root.right != null){
            //挑选左子树中最大的或者右子树中最小的,替换当前节点,再将替换的节点置空
             int val = findMaxInLeftTree(root.left);
             root.val = val;
             root.left = deleteNode(root.left, val);
             return root;
         }
        return root;

     }
     //找到左子树中最大的值
    private int findMaxInLeftTree(TreeNode left) {
        if(left == null){
            return 0;
        }
        if(left.right == null){
            return left.val;
        }
        if(left.right == null && left.left == null){
            return left.val;
        }
        return findMaxInLeftTree(left.right);
    }
}
  • 15
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值