前言:在学习BST时,发现查找插入等操作都很好理解和实现,而删除节点的操作情况比较复杂,故通过自己的理解整理如下,本文适合初学者理解并自己动手实现BST删除操作。

在很多文章中提到,删除节点可以考虑以下三种情况:

  1. 没有左右子节点
  2. 存在左节点或者右节点
  3. 同时存在左右子节点

这种思路是最简单的思路很好理解,但是实现起来会发现代码有点冗杂。在本文中,将按照以下思路来进行讲解:

  1. 没有左子树(包括了没有左子树有右子树,没有左子树也没有右子树)
  2. 有左子树但没有右子树
  3. 既有左子树,又有右子树

首先,我们来想一下删除一个单链表的节点该如何操作?(1)找到要删除的节点,(2)记录该节点的前一个节点(3)将前一节点链接到该节点的后一节点。这样就将该节点所隔离,根据java的垃圾回收机制,该节点将被删除回收内存。

那么如果二叉树就像一个单链表一样,那不是就很好解决了?所以删除二叉树节点的基本情况就是要删除的节点没有左子树,或者没有右子树(current.left==null || current.right==null),这时少了一路分支,处理起来就像单链表一样,分为三步:(1)找到要删除的节点(2)记录该节点的父节点(3)将父节点链接到该节点的后一节点。但是在执行第三步的时候要注意:父节点有left和right两个指针,需要判断是哪个指针,也就是current是父节点的左子树还是右子树;该节点的后一节点就是那个唯一的不为空的节点。

情况一:没有左子树

情况二:有左子树没有右子树

下图分别给出了要删除的节点只有右子树,只有左子树,左右子树都没有(叶子节点)的情况。

         

下面给出基本情况的代码:

//cur指向要被删除的节点if(cur==null)return false;//第一种情况:没有左子树(包括了没有做子树有右子树,没有左子树也没有右子树)if(cur.left==null){if(parent==null){//特殊情况:根节点root=cur.right;}else{if(e.compareTo(parent.val)<0)//cur是parent的左子节点parent.left=cur.right;else//cur是parent的右子节点parent.right=cur.right;}}//情况二:有左子树没有右子树else if(cur.right == null){if(parent==null){//根节点root=cur.left;}else{if(e.compareTo(parent.val)<0)//cur是parent的左子节点parent.left=cur.left;else//cur是parent的右子节点parent.right=cur.left;}}else{//稍后添加return false;}

情况三:有左子树,又有右子树;

这时如果单纯地将父节点连接到该节点的左子节点或者右子节点都会导致另外一个子树没有被链接而被删除,所以我们要找到一个合适的值来代替该节点的位置,再删除这个值。什么是一个合适的值?(1)该值要确保BST树的基本性质,也就是说放在要删除节点的位置上,大于它的左节点而小于他的右节点(2)该值应该是前面的基本情况中的一种,也就是说没有左子树,或者没有右子树。所以方法有两种:从当前节点的左子节点的右子树中找出最大值,也就是最右节点(没有右子树);或者从当前节点的右子节点的左子树中找出最小值,也就是最左节点(没有左子树);下面给出第三种情况的思路图:

第一步:定位到要删除20这个节点,发现属于情况三;第二步:找到该节点左子树的最大值(最右节点),为18;第三步:将18复制到要删除的节点处;第四步:将18的父节点的右子节点(因为18是父节点的右子节点)链接到18的左子节点(最右节点没有右子节点)。

下面给出完整的代码:

    public boolean delete(E e){TreeNode<E> parent=null;TreeNode<E> cur=root;//首先定位要删除节点的位置while(cur!=null){if(e.compareTo(cur.val)<0){parent=cur;cur=cur.left;}else if(e.compareTo(cur.val)>0){parent=cur;cur=cur.right;}elsebreak;}//cur指向要被删除的节点if(cur==null)return false;//第一种情况:没有左子树(包括了没有做子树有右子树,没有左子树也没有右子树)if(cur.left==null){if(parent==null){//根节点root=cur.right;}else{if(e.compareTo(parent.val)<0)//cur是parent的左子节点parent.left=cur.right;else//cur是parent的右子节点parent.right=cur.right;}}//情况二:有左子树没有右子树else if(cur.right == null){if(parent==null){//根节点root=cur.left;}else{if(e.compareTo(parent.val)<0)//cur是parent的左子节点parent.left=cur.left;else//cur是parent的右子节点parent.right=cur.left;}}//情况三:有左子树,又有右子树;else{TreeNode<E> parentOfRightMost=cur;TreeNode<E> rightMost=cur.left;//找左子树中的最大值,则需要从左子树的右节点找while(rightMost.right!=null){parentOfRightMost=rightMost;rightMost=rightMost.right;}//当前要删除节点的左子树下的最右节点是最大值,该值一定大于左子树的值(因为是右节点)//并且小于当前节点的右节点的值,因为是左子树下的分支。所以用该值代替要删除的节点,仍然满足左子节点小于根节点,右子节点大于根节点cur.val=rightMost.val;if(parentOfRightMost.right==rightMost)//这种情况是确实找到了最右节点,也就是说该节点没有右子树,可能有左子树parentOfRightMost.right=rightMost.left;//把剩下的子树连接上else//这种情况是没有执行while,该节点就是当前节点的左子节点(parentOfRightMost.left),而且没有右子树(rightMost.left)parentOfRightMost.left=rightMost.left;}/*else{TreeNode<E> parentOfRightMost=cur;TreeNode<E> rightMost=cur.right;//找右子树中的最小值,则需要从右子树的左节点找while(rightMost.left!=null){parentOfRightMost=rightMost;rightMost=rightMost.left;}cur.val=rightMost.val;if(parentOfRightMost.left==rightMost)parentOfRightMost.right=rightMost.right;elseparentOfRightMost.left=rightMost.right;*/size--;return true;}

至此,已经完成了整个删除过程,剩下的大家可以自己写一个代码测试一下这三种情况的删除。

二叉搜索树(BST)删除节点--思路清晰相关推荐

  1. 算法:二叉搜索树BST - 删除节点 详解(Java实现)

    删除节点 删除节点存在 3 种情况,几乎所有类似博客都提到了这点.这 3 种情况分别如下: 没有左右子节点,可以直接删除 存在左节点或者右节点,删除后需要对子节点移动 同时存在左右子节点,不能简单的删 ...

  2. 阿里开发者招聘节 | 面试题02-04:给定一个二叉搜索树(BST),找到树中第K小的节点

    为帮助开发者们提升面试技能.有机会入职阿里,云栖社区特别制作了这个专辑--阿里巴巴资深技术专家们结合多年的工作.面试经验总结提炼而成的面试真题这一次将陆续放出(面试题官方参考答案将在专辑结束后统一汇总 ...

  3. 二叉搜索树(BST)的删除算法原理解析

    二叉搜索树的删除算法主要分两种情况: 1.要删除的节点只有一个孩子(左孩子或右孩子),这种情况比较简单,只需要将该孩子连接到当前节点的父节点即可. 下面重点讲讲第二种情况: 2.第二种情况便是要删除的 ...

  4. 二叉搜索树BST的学习

    文章目录 二叉搜索树BST 什么是BST? 用BST做什么? 一.BST的特性 BST的特性是什么? 1.[230. 二叉搜索树中第K小的元素](https://leetcode.cn/problem ...

  5. 二叉搜索树(BST的理论剖析+代码实现)

    二叉搜索树(BST树) 文章目录 二叉搜索树(BST树) 1.二叉搜索树的概念 2.二叉搜索树的结构定义 2.1 二叉搜索树结点模板的定义 2.2 二叉搜索树类模板的定义 3.二叉搜索树的效率 4.二 ...

  6. 看动画学算法之:二叉搜索树BST

    文章目录 简介 BST的基本性质 BST的构建 BST的搜索 BST的插入 BST的删除 看动画学算法之:二叉搜索树BST 简介 树是类似于链表的数据结构,和链表的线性结构不同的是,树是具有层次结构的 ...

  7. 真c++ 从二叉树到红黑树(3)之二叉搜索树BST

      此文章为从二叉树到红黑树系列文章的第三节,主要介绍介绍二叉搜索树BST,为AVL和RedBlack打下基础 文章目录 一.前面文章链接~(点击右边波浪线可以返回目录) 二.二叉搜索树BST的定义~ ...

  8. 08_Python算法+数据结构笔记-二叉搜索树查询/删除-AVL树旋转/插入/应用-贪心算法

    b站视频:路飞IT学城 清华计算机博士带你学习Python算法+数据结构_哔哩哔哩_bilibili #71 二叉搜索树:查询 import randomclass BiTreeNode:def __ ...

  9. 五.树,二叉树,二叉搜索树(BST)和自平衡二叉搜索树(AVL)

    1.树 树是一种数据结构 比如:目录结构 树是一种可以递归定义的数据结构 树是由n个节点组成的集合: 如果 n=0, 那这是一颗空树 如果 n>0, 那存在1个节点作为树的根节点,其他节点可以分 ...

  10. 二叉搜索树BST红黑树

    二叉搜索树基础知识 提起红黑树咱们肯定要先说说这个二叉搜索树(BST) 二叉搜索树又叫二叉查找树,二叉排序树:它具有以下特点: 如果它的左子树不为空,则左子树上结点的值都小于根结点. 如果它的右子树不 ...

最新文章

  1. 数据库系统概论:第七章 数据库设计
  2. mysql 列名能不能写成col1、col2_Mysql 寒假刷题TIPs
  3. idea未进行快捷键配置时的快捷键
  4. debian下运行netstat失败
  5. NSArray创建和使用
  6. Spring 基于注解的配置
  7. 【论文笔记】From Facial Parts Responses to Face Detection: A Deep Learning Approach
  8. help/Makefile.am:21: error: USE_NLS does not appear in AM_CONDITIONAL
  9. 结构风险最小和VC维理论的解释
  10. 深入浅出python学习
  11. 双系统——彻底删除ubuntu
  12. 微生物测序分析LEfSe
  13. css 从右到左的方向调整
  14. 罪恶装备X出招表[zz]
  15. 【校招VIP】产品设计分析之文案功底考察
  16. 王境泽表情包出处,怎么制作GIF动态图?
  17. 磁盘阵列柜 和存储有什么区别
  18. 射影几何----渐近线方程公式
  19. 深度学习入门笔记(十八):卷积神经网络(一)
  20. 有源滤波器空间矢量不定频滞环控制matlab仿真

热门文章

  1. 软件设计模式—单例模式
  2. Android获取手机本地图片并显示
  3. 浅谈小程序开发遇到过的问题
  4. python_面向对象进价
  5. 微信公众号被封怎么办
  6. 彻底搞懂图的广度优先算法
  7. 尊重兴趣,是尊重生命深处的本能
  8. python分解质因数递归_Python 正整数分解质因数具体实现附代码
  9. 超级有爱的五款APP共享 可以让你神操作
  10. ABAP-Generate dynpro动态屏幕