前置知识

二叉树的结构

    public class TreeNode {
int val;
TreeNode left;
TreeNode right; TreeNode() {
} TreeNode(int val) {
this.val = val;
}
}

中序遍历

  • 中序遍历:对于每一个节点,遍历顺序是:左子树->当前节点->右子树
  • 中序遍历得到的第一个节点是没有左子树的(也许是叶子节点,也许有右子树)
  • 同理,中序遍历的最后一个节点没有右子树

代码递归实现

    public void inorder_traversal(TreeNode root) {
if (root == null) {
return;
}
if (root.left != null) {
inorder_traversal(root.left);
}
System.out.println(root.val);
if (root.right != null) {
inorder_traversal(root.right);
}
}

二叉搜索树的定义

  1. 左子树的所有节点大于当前节点
  2. 右子树的所有节点小于当前节点
  3. 每一个节点的值都不相同
  4. 中序遍历的结果是升序的

这些定义决定了它的优点:查找效率快,因为二叉搜索树查找一个值时,自带二分查找的方式

下图就是一个标准的二叉搜索树

查找节点

给定一个值,使用循环在二叉搜索树中查找,找到该节点为止

  1. 从根节点开始,进行比较
  2. 给定值大于根节点就找右子树
  3. 给定值小于根节点就找左子树

代码实现如下

public TreeNode search(TreeNode root, int val) {
// 节点不为空,且不等于特定值
while(root != null && root.val != val){
if(root.val > val){
root = root.left;
}else{
root = root.right;
}
}
return root;
}

添加节点

二叉搜索树的添加是将新的节点作为叶子节点加入到其中,因为叶子节点的增加比较简单。

  1. 跟搜索过程类似,从根节点开始找,如果,如果小,找到一个适合新节点的位置

    1. 新节点的值比当前节点大(小),并且右(左)子树为空,插入到当前节点的右(左)子树中
    2. 如果当前节点的子树不为空,继续往下寻找
  2. 然后使用一个pre节点,由pre节点作为父节点添加新节点
  • 有可能要插入节点的二叉树是一颗空树,创建一个新的二叉树
  • 如果新节点的值已经存在二叉树中,不需要进行添加
    public TreeNode insertInto(TreeNode root, int val) {

        if (root == null) {
// 树为空树的情况
return new TreeNode(val);
}
// 一个临时节点指向根节点,用于返回值
TreeNode tmp = root;
TreeNode pre = root; while (root != null && root.val != val) {
// 保存父节点
pre = root;
if (val > root.val) {
root = root.right;
} else {
root = root.left;
}
}
// 通过父节点添加
if (val > pre.val) {
pre.right = new TreeNode(val);
} else {
pre.left = new TreeNode(val);
}
return tmp;
}

删除节点

二叉搜索树删除节点的过程比较复杂,因为被删除节点可能是以下三种情况

  1. 叶子节点
  2. 有一个子节点
  3. 有两个子节点

删除叶子节点

直接搜索到相应的节点,然后删除,叶子节点的删除不影响树的性质

有一个子节点的节点

将节点删除,让父节点连接子节点即可,因为子节点与父节点的关系 = 当前节点与父节点的关系,并不改变树的性质

  • 二叉搜索树的定义决定了:当前节点 大于(小于) 父节点,那么它的子节点 大于(小于) 父节点

过程像这张图一样

删除有两个子节点的节点

我们可以通过交换节点的方式,让要删除节点和只有一个子节点的节点交换,删除节点的操作就变成了上面的情况。

二叉搜索树中序遍历的结果是升序的,如果要交换,肯定要找中序遍历在该节点左右两边的节点(值交换之后也满足二叉搜索树的定义)

  • 中序遍历的后(前)一个节点是右(左)子树中序遍历的第一个(最后一个)节点,而且它们都只有一个子节点

过程跟下面这张图类似(与中序遍历的后一个节点交换,并删除这个节点)

代码实现

public TreeNode deleteNode(TreeNode root, int key) {
TreeNode tmp = root; TreeNode pre = root; // 寻找要删除的节点
while (root != null && root.val != key) {
pre = root;
if (key > root.val) {
root = root.right;
} else {
root = root.left;
}
}
// 找不到符合的节点值
if (root == null) {
return tmp;
} // 只有一个子节点的情况
if (root.left == null || root.right == null) {
if (root.left == null) {
// 要删除的是根节点,返回它的子节点
if (root == tmp) {
return root.right;
}
// 使用父节点连接子节点,实现删除当前节点
if (pre.left == root) {
pre.left = root.right;
} else {
pre.right = root.right;
}
} else {
if (root == tmp) {
return root.left;
}
if (pre.left == root) {
pre.left = root.left;
} else {
pre.right = root.left;
}
}
return tmp;
} // 第一种方式
// 寻找中序遍历的后一个节点,也就是右子树进行中序遍历的第一个节点,右子树的最左节点
pre = root;
TreeNode rootRight = root.right;
while (rootRight.left != null) {
pre = rootRight;
rootRight = rootRight.left;
} // 节点的值进行交换
int tmpVal = rootRight.val;
rootRight.val = root.val;
root.val = tmpVal; // 中序遍历的第一个节点肯定是没有左子树的,但是可能有右子树,将右子树连接到父节点上(相当于删除有一个子节点的节点)
if (pre.left == rootRight) {
pre.left = rootRight.right;
}else {
pre.right = rootRight.right;
} // 第二种方式
// 寻找中序遍历的前一个节点,也就是左子树进行中序遍历的最后一个节点,左子树的最右节点
// pre = root;
// TreeNode rootLeft = root.left;
// while (rootLeft.right != null){
// pre = rootLeft;
// rootLeft = rootLeft.right;
// }
//
// int tmpVal = rootLeft.val;
// rootLeft.val = root.val;
// root.val = tmpVal;
//
// // 中序遍历的最后一个节点肯定是没有右子树的,但是可能有左子树,将左子树连接到父节点上(相当于删除有一个子节点的节点)
// if (pre.left == rootLeft) {
// pre.left = rootLeft.left;
// }else {
// pre.right = rootLeft.left;
// } return tmp;
}

Java实现二叉搜索树的插入、删除的更多相关文章

  1. Java对二叉搜索树进行插入、查找、遍历、最大值和最小值的操作

    1.首先,须要一个节点对象的类.这些对象包括数据.数据代表存储的内容,并且还有指向节点的两个子节点的引用 class Node { public int iData; public double dD ...

  2. Java实现二叉搜索树

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11406176.html 尝试一下用Java实现二叉搜索树/二叉查找树,记录自己的学习历程. 1 ...

  3. Java创建二叉搜索树,实现搜索,插入,删除操作

    Java实现的二叉搜索树,并实现对该树的搜索,插入,删除操作(合并删除,复制删除) 首先我们要有一个编码的思路,大致如下: 1.查找:根据二叉搜索树的数据特点,我们可以根据节点的值得比较来实现查找,查 ...

  4. Java实现二叉搜索树的添加,前序、后序、中序及层序遍历,求树的节点数,求树的最大值、最小值,查找等操作

    什么也不说了,直接上代码. 首先是节点类,大家都懂得 /** * 二叉树的节点类 * * @author HeYufan * * @param <T> */ class Node<T ...

  5. Java实现二叉搜索树及相关操作

    package com.tree; import com.tree.BitNode; /** * * 二叉搜索树:一个节点的左子节点的关键字小于这个节点.右子节点的关键字大于或等于这个父节点 * * ...

  6. Java数据结构——二叉搜索树

    定义二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若 ...

  7. 第七章 二叉搜索树 07B2-1 插入:算法

  8. 树-二叉搜索树-AVL树

    树-二叉搜索树-AVL树 树 树的基本概念 节点的度:节点的儿子数 树的度:Max{节点的度} 节点的高度:节点到各叶节点的最大路径长度 树的高度:根节点的高度 节点的深度(层数):根节点到该节点的路 ...

  9. 二叉搜索树Java实现(查找、插入、删除、遍历)

    由于最近想要阅读下 JDK1.8 中 HashMap 的具体实现,但是由于 HashMap 的实现中用到了红黑树,所以我觉得有必要先复习下红黑树的相关知识,所以写下这篇随笔备忘,有不对的地方请指出- ...

随机推荐

  1. 虚拟机+OS系统安装+Xshell

    安装虚拟机 1.先下载好VMware Workstation.exe的安装包(最好直接下载破解版(非最新版) 在此私人网址不公布 可直接百度 资源很多) 2.直接下一步 直到安装完成(注意最好不要装在 ...

  2. Windows通过计划任务定时执行bat文件

    第一步 第二步 第三步 第四步 第五步 第六步

  3. Docker从入门到精通(七)——容器数据共享

    什么是容器数据共享?简单来说就是容器与容器之间数据共享,容器与宿主机数据共享. 1.为什么需要数据共享? ①.数据持久化 比如我们有一个MySQL集群,通过容器启动,那么项目运行过程中的数据是保存在容 ...

  4. Spring Boot发布2.6.2、2.5.8:升级log4j2到2.17.0

    12月22日,Spring官方发布了Spring Boot 2.5.8(包括46个错误修复.文档改进和依赖项升级)和2.6.2(包括55个错误修复.文档改进和依赖项升级). 这两个版本均为缺陷修复版本 ...

  5. idea删除同一个模块后新建模块显示被占用

    当我们某个模块因为什么原因需要删除重建的时候 ,输入完模块名称并不能创建出来,这是因为模块已经被注册 解决办法: 1.右键点击项目名称---选择Load/Unload Modules 2.将已经删除的 ...

  6. ReentrantLock可重入锁——源码详解

    开始这篇博客之前,博主默认大家都是看过AQS源码的~什么居然没看过猛戳下方 全网最详细的AbstractQueuedSynchronizer(AQS)源码剖析(一)AQS基础 全网最详细的Abstra ...

  7. MyBatis学习(四)MyBatis一对一关联查询

    一对一关联查询即.两张表通过外键进行关联.从而达到查询外键直接获得两张表的信息.本文基于业务拓展类的方式实现. 项目骨架 配置文件conf.xml和db.properties前几节讲过.这里就不细说了 ...

  8. XSS工具类,清除参数中的特殊字符

    package com.xss; import java.util.regex.Pattern; /** * XssUtil 工具类 */ public class XssUtil { static ...

  9. 【九度OJ】题目1433:FatMouse 解题报告

    [九度OJ]题目1433:FatMouse 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1433 题目描述: FatMouse pr ...

  10. 【LeetCode】996. Number of Squareful Arrays 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 回溯法 日期 题目地址:https://leetco ...