Java实现二叉搜索树的插入、删除(1)

}

}

中序遍历

  • 中序遍历:对于每一个节点,遍历顺序是:左子树->当前节点->右子树

  • 中序遍历得到的第一个节点是没有左子树的(也许是叶子节点,也许有右子树)

  • 同理,中序遍历的最后一个节点没有右子树

代码递归实现

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. 跟搜索过程类似,从根节点开始找,如果,如果小,找到一个适合新节点的位置

  2. 新节点的值比当前节点大(小),并且右(左)子树为空,插入到当前节点的右(左)子树中

  3. 如果当前节点的子树不为空,继续往下寻找

  4. 然后使用一个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;

最后

小编精心为大家准备了一手资料

以上Java高级架构资料、源码、笔记、视频。Dubbo、Redis、设计模式、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术

【附】架构书籍

  1. BAT面试的20道高频数据库问题解析
  2. Java面试宝典
  3. Netty实战
  4. 算法

BATJ面试要点及Java架构师进阶资料

[外链图片转存中…(img-pVu1LUzT-1714358907710)]

以上Java高级架构资料、源码、笔记、视频。Dubbo、Redis、设计模式、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术

【附】架构书籍

  1. BAT面试的20道高频数据库问题解析
  2. Java面试宝典
  3. Netty实战
  4. 算法

[外链图片转存中…(img-JUYOMZnU-1714358907710)]

BATJ面试要点及Java架构师进阶资料

[外链图片转存中…(img-hnxjslWy-1714358907711)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值