Java删除二叉搜索树的任意元素的方法详解

作者:WFaceBoss 时间:2021-10-04 12:27:26 

本文实例讲述了Java删除二叉搜索树的任意元素的方法。分享给大家供大家参考,具体如下:

一.删除思路分析

在删除二叉搜索树的任意元素时,会有三种情况:

1.1 删除只有左孩子的节点

节点删除之后,将左孩子所在的二叉树取代其位置;连在原来节点父亲元素右节点的位置,比如在图中需要删除58这个节点。

Java删除二叉搜索树的任意元素的方法详解

删除58这个节点后,如下图所示:

Java删除二叉搜索树的任意元素的方法详解

 

 

1.2 删除只有右孩子的节点:

节点删除之后,将右孩子所在的二叉树取代其位置;连在原来节点的位置,比如在下图中需要删除58这个节点。

Java删除二叉搜索树的任意元素的方法详解

删除58这个节点后,如下图所示:

Java删除二叉搜索树的任意元素的方法详解

这里需要说明说一下,以上两种情况其实包含了叶子节点情况的,我们可以把叶子节点理解成只有左孩子的节点,也可以把它理解为只有右孩子的节点,只不过左孩子、右孩子为null

1.3 删除包含左右孩子的节点

如下图,二叉搜索树包含有左右孩子,假设现需要删除58这个节点。

Java删除二叉搜索树的任意元素的方法详解

针对该种情况,分析如下:
我们把58这个节点记为d节点(包含有左子树与右子树),如下图所示:

Java删除二叉搜索树的任意元素的方法详解

针对这种节点删除情况需要把左子树与右子树融合起来,融合方法:
d这节点的左孩子与右孩子中找一个比d节点还要大的节点取代d节点,根据二叉搜索树的性质可知(左边节点<当前节点<右边节点),这个需要被找的节点存在于d节点的右孩子节点中。

寻找规则:
寻找需要被删除节点58(d)的后继的所有元素中,离 58 最近的且比 58 大的节点,在本例中为59这个节点【即右子树中的最小值】,记为s,如下图所示:

Java删除二叉搜索树的任意元素的方法详解

删除步骤:

(1)从d的右子树中删除最小值,将删除最小值s后的d的右子树, 变为d后继节点s的右孩子,如下图所示:

Java删除二叉搜索树的任意元素的方法详解

(2)将d节点(58节点)的左子树,变为后继节点s(59节点)的左子树,如下图所示:

Java删除二叉搜索树的任意元素的方法详解

(3)将后继节点s59节点)连接到d节点(58节点)父亲节点的右边,删除d节点(58节点)后,后继s节点(59节点)成为新的根,如下图所示:

Java删除二叉搜索树的任意元素的方法详解

二、编码实现二叉搜索树的任意元素

根据上述的分析,在此基础上进行编码,删除代码如下:


//从二叉搜索树中删除元素为e的节点
 public void remove(E e) {
   root = remove(root, e);
 }

//删除以node为根的二叉搜索树中值为e的节点,递归算法
 //返回删除节点后更新的二叉搜索树的根
 private Node remove(Node node, E e) {
   if (node == null)
     return null;

if (e.compareTo(node.e) < 0) {//e<node.e (被删除元素e小于当前节点值e)
     node.left = remove(node.left, e);
     return node;
   }
   if (e.compareTo(node.e) > 0) {//e>node.e (被删除元素e大于当前节点值e)
     node.right = remove(node.right, e);
     return node;
   } else {//e==node.e (被删除元素e等于当前节点值e)

//待删除节点左子树为空情况
     if (node.left == null) {
       Node rightNode = node.right;
       node.right = null;
       size--;
       return rightNode;
     }

//待删除节点右子树为空情况
     if (node.right == null) {
       Node leftNode = node.left;
       node.left = null;
       size--;
       return leftNode;
     }

//左右子树均不为空
     //方法:找到比待删除节点大的最小节点,即待删除节点右子树的最小节点
     //用这个节点顶替待删除节点的位置
     Node successor = minimum(node.right);
     successor.right = removeMin(node.right);
     successor.left = node.left;
     node.left = node.right = null;

return successor;
   }
 }

对于上述代码中的minimum函数,在5.3节中已经实现,此处同样也把代码列出来:


// 寻找二分搜索树的最小元素
 public E minimum() {
   if (size == 0) {
     throw new IllegalArgumentException("BST is empty");
   }

Node ninNode = minimum(root);
   return ninNode.e;
 }

// 返回以node为根的二分搜索树的最小值所在的节点
 private Node minimum(Node node) {
   if (node.left == null) {
     return node;
   }

//返回相应的节点的左子树的最小值
   return minimum(node.left);
 }

源码地址 https://github.com/FelixBin/dataStructure/blob/master/src/BST/BST.java

希望本文所述对大家java程序设计有所帮助。

来源:https://www.cnblogs.com/wfaceboss/p/10694736.html

标签:Java,二叉搜索树
0
投稿

猜你喜欢

  • Android 判断某个Activity 是否在前台运行的实例

    2023-07-24 19:29:21
  • Java设计模式之抽象工厂模式实例详解

    2023-11-29 04:04:57
  • C语言/C++中如何产生随机数

    2023-06-25 08:48:57
  • SpringBoot定时任务两种(Spring Schedule 与 Quartz 整合 )实现方法

    2023-11-01 16:03:39
  • SpringBoot中多环境配置和@Profile注解示例详解

    2023-11-29 05:39:04
  • Flutter ListView 上拉加载更多下拉刷新功能实现方法

    2023-06-25 19:51:57
  • IOS与网页JS交互详解及实例

    2023-07-08 11:58:20
  • 深入剖析Android消息机制原理

    2023-09-30 01:57:11
  • 细谈java同步之JMM(Java Memory Model)

    2023-11-23 13:09:33
  • 浅谈Java中向上造型向下造型和接口回调中的问题

    2023-11-09 13:51:46
  • add方法理解ArrayList的扩容机制

    2023-11-24 02:16:28
  • JAVA实现单例模式的四种方法和一些特点

    2023-11-02 05:38:20
  • JPA save()方法将字段更新为null的解决方案

    2023-10-28 22:29:28
  • Java调用接口如何获取json数据解析后保存到数据库

    2023-11-16 15:01:36
  • Java开发环境jdk 1.8安装配置方法(Win7 64位系统/windows server 2008)

    2022-05-11 20:00:58
  • c# 获取CookieContainer的所有cookies函数代码

    2023-06-17 23:11:30
  • 基于Java数组实现循环队列的两种方法小结

    2023-06-30 16:09:01
  • jvm调优的几种场景(小结)

    2023-04-11 18:37:04
  • 基于javaMybatis存进时间戳的问题

    2023-11-29 02:55:51
  • Spring注解驱动之BeanDefinitionRegistryPostProcessor原理解析

    2023-11-24 23:24:21
  • asp之家 软件编程 m.aspxhome.com