文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java怎么实现二叉搜索树的插入、删除功能

2023-06-26 05:53

关注

这篇文章给大家介绍Java怎么实现二叉搜索树的插入、删除功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

Java的特点有哪些

Java的特点有哪些 1.Java语言作为静态面向对象编程语言的代表,实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。 2.Java具有简单性、面向对象、分布式、安全性、平台独立与可移植性、动态性等特点。 3.使用Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等。

二叉树的结构

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

中序遍历

只有当它的左子树都被遍历过了(或者没有左子树),它才会被遍历到。
在遍历右子树之前,一定会先遍历当前节点。

代码递归实现

List<TreeNode> list = new ArrayList<>();    public void inorder_traversal(TreeNode root) {        if (root == null) {            return;        }        if (root.left != null) {            inorder_traversal(root.left);        }        list.add(root);        if (root.right != null) {            inorder_traversal(root.right);        }    }

二叉搜索树的定义

这些定义决定了它的优点:查找效率快,因为二叉搜索树查找一个值时,可以通过二分查找的方式,平均时间复杂度为log2(n),n是二叉树的层树

下图就是一个标准的二叉搜索树,右子树比根节点大,左子树比根节点小

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;    }

添加节点

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

b值比当前节点大(小),并且当前节点的右(左)子树为空,将b插入到当前节点的右(左)子树中
如果当前节点的子树不为空,继续往下寻找

 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;    }

删除节点

删除过程比较复杂,先设二叉搜索树要删除的节点为a,a有以下三种情况

过程类似搜索节点,找到到a后,通过它的父节点删除,并且叶子节点的删除不影响树的性质

有一个子节点的节点

要将a删除,并且保留a的子节点,让它的父节点连接它的子节点即可,因为a的子节点 与 a的父节点 关系 == a与 a的父节点 关系,所以不改变树的性质

过程像这张图一样

Java怎么实现二叉搜索树的插入、删除功能

删除有两个子节点的节点

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

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

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

Java怎么实现二叉搜索树的插入、删除功能

代码实现

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怎么实现二叉搜索树的插入、删除功能就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯