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

代码实现如下

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;

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;

最后

最后,强调几点:

  • 1. 一定要谨慎对待写在简历上的东西,一定要对简历上的东西非常熟悉。因为一般情况下,面试官都是会根据你的简历来问的; 能有一个上得了台面的项目也非常重要,这很可能是面试官会大量发问的地方,所以在面试之前好好回顾一下自己所做的项目;
  • 2. 和面试官聊基础知识比如设计模式的使用、多线程的使用等等,可以结合具体的项目场景或者是自己在平时是如何使用的;
  • 3. 注意自己开源的Github项目,面试官可能会挖你的Github项目提问;

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目。

面试答案

三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里

三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里

三面头条+四面阿里+五面腾讯拿offer分享面经总结,最终入职阿里

项目,面试官可能会挖你的Github项目提问;

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目。

面试答案

[外链图片转存中…(img-bI35haVN-1714358932820)]

[外链图片转存中…(img-bj9cbakH-1714358932820)]

[外链图片转存中…(img-CROEU30S-1714358932821)]

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值