首页 > 编程语言 >Java中的二叉搜索树(如果想知道Java中有关二叉搜索树的知识点,那么只看这一篇就足够了!)

Java中的二叉搜索树(如果想知道Java中有关二叉搜索树的知识点,那么只看这一篇就足够了!)

时间:2024-07-29 19:58:22浏览次数:15  
标签:right Java cur parent 二叉 搜索 节点 left

        前言:Java 提供了丰富的数据结构来处理和管理数据,其中 TreeSet 和 TreeMap 是基于红黑树实现的集合和映射接口。它们有序地存储数据,提供高效的搜索、插入和删除操作。


✨✨✨这里是秋刀鱼不做梦的BLOG

✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客

先让我们看一下本文大致的讲解内容:

目录

1.二叉搜索树的认识

        (1)二叉搜索树的概念

        (2)二叉搜索树的性质

2.有关二叉搜索树的常用操作

        【1】插入操作

        【2】查找操作

        【3】删除操作

1.cur.left == null

2.cur.right == null

3.cur.left != null && cur.right != null

3.二叉树的应用场景

1. 数据结构和算法

2. 数据库和文件系统

3. 图形和游戏开发


1.二叉搜索树的认识

        (1)二叉搜索树的概念

        在开始学习TreeSet与TreeMap之前,我们需要先学习一下Java中的二叉搜索树,二叉搜索树是一种特殊的二叉树,其中每个节点都有一个值,并满足以下性质:

  • 对于每个节点,左子树所有节点的值都小于该节点的值。

  • 对于每个节点,右子树所有节点的值都大于该节点的值。

如图:

从上图中我们可以很明显的观察出二叉搜索树的上述两个特性。

        (2)二叉搜索树的性质

        在了解完了二叉搜索树的概念之后,我们需要学习一下有关二叉搜索树的性质,对于一棵二叉搜索树而言,其都有以下三个性质:

  • 有序性:二叉搜索树的中序遍历结果是一个递增的有序序列。

  • 动态性:二叉搜索树支持动态插入和删除操作,适用于需要频繁更新的数据集合。

  • 查找效率:在理想情况下,二叉搜索树的查找、插入和删除操作的时间复杂度为 O(log n)。

        ——这里读者可能会对其中的一些性质不是很理解,没有关系,继续向下进行阅读即可,在后续的文本中,我们会慢慢的理解其中的意思。

2.有关二叉搜索树的常用操作

        【1】插入操作

        插入操作用于向二叉搜索树中插入新值。插入过程从根节点开始,根据当前节点的值与新值的比较结果,决定将新值插入到左子树还是右子树。

以下是实现该操作的代码:

public void insertNode(int key) {
    // 如果根节点为空,直接插入新节点作为根节点
    if (root == null) {
        root = new TreeNode(key);
        return;
    }

    // 初始化当前节点为根节点,父节点为null
    TreeNode cur = root;
    TreeNode parent = null;
    TreeNode node = new TreeNode(key);

    // 寻找合适的位置插入节点
    while (cur != null) {
        if (cur.val < key) { // 当前值小于插入值,向右子树移动
            parent = cur;
            cur = cur.right;
        } else if (cur.val > key) { // 当前值大于插入值,向左子树移动
            parent = cur;
            cur = cur.left;
        } else { // 当前值等于插入值,直接返回,不插入重复值
            return;
        }
    }

    // 根据父节点值与插入值的比较结果,插入新节点到左子树或右子树
    if (parent.val > key) {
        parent.left = node;
    } else {
        parent.right = node;
    }
}

读者可以跟着下面的解释来对上边的代码进行理解:

  1. 根节点为空检查

    • 如果 root 为空,直接将新节点 TreeNode(key) 作为根节点插入,并返回。
  2. 初始化当前节点和父节点

    • cur 用于遍历树,从 root 开始。
    • parent 用于记录 cur 的父节点。
  3. 寻找合适的插入位置

    • cur 不为空时,比较 cur.valkey
      • 如果 cur.val 小于 key,移动到右子树。
      • 如果 cur.val 大于 key,移动到左子树。
      • 如果 cur.val 等于 key,直接返回,不插入重复值。
  4. 插入新节点

    • 根据 parent.valkey 的比较结果,将新节点插入到 parent 的左子树或右子树。

        ——这样我们就学会了插入操作了!

        【2】查找操作

        查找操作用于在二叉搜索树中查找特定值。查找过程从根节点开始,根据当前节点的值与目标值的比较结果,决定在左子树还是右子树继续查找。

以下是实现该操作的代码:

public TreeNode search(int key) {
    // 初始化当前节点为根节点
    TreeNode cur = root;
    
    // 遍历树,直到找到目标节点或遍历到空节点
    while (cur != null) {
        if (cur.val < key) { // 当前节点值小于目标值,移动到右子树
            cur = cur.right;
        } else if (cur.val > key) { // 当前节点值大于目标值,移动到左子树
            cur = cur.left;  // 这里应修正为cur = cur.left;
        } else { // 找到目标节点
            return cur;
        }
    }
    // 如果没有找到目标节点,返回 null
    return null;
}

读者可以跟着下面的解释来对上边的代码进行理解:

  1. 初始化当前节点

    • cur 用于遍历树,从 root 开始。
  2. 遍历树

    • cur 不为空时,比较 cur.valkey
      • 如果 cur.val 小于 key,移动到右子树 (cur = cur.right)。
      • 如果 cur.val 大于 key,移动到左子树 (cur = cur.left)。
      • 如果 cur.val 等于 key,返回当前节点。
  3. 返回结果

    • 如果遍历完整棵树没有找到目标节点,返回 null

        【3】删除操作

        删除操作用于从二叉搜索树中删除指定值。删除节点分为三种情况:叶子节点、只有一个子节点的节点和有两个子节点的节点。

        由于删除操作比较哦啊复杂,所以我们这里重点讲解一下,对于删除操作,我们可能会有以下的可能情况:

——现在我们假设待删除结点为 cur, 待删除结点的双亲结点为 parent:

1.cur.left == null

        1. cur 是 root,则 root = cur.right
        2. cur 不是 root,cur 是 parent.left,则 parent.left = cur.right
        3. cur 不是 root,cur 是 parent.right,则 parent.right = cur.right

2.cur.right == null

        1. cur 是 root,则 root = cur.left
        2. cur 不是 root,cur 是 parent.left,则 parent.left = cur.left

        3. cur 不是 root,cur 是 parent.right,则 parent.right = cur.left

3.cur.left != null && cur.right != null

        这时我们就需要使用替换法进行删除,即在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点中,再来处理该结点的删除问题

我们大致了解了删除的三种可能的大情况之后,现在让我们尝试着编写一下代码:

public void remove(int key) {
    TreeNode parent = null; // 父节点初始化为 null
    TreeNode cur = root; // 当前节点初始化为根节点
    // 遍历树,寻找要删除的节点
    while (cur != null) {
        if (cur.val < key) { // 当前值小于目标值,移动到右子树
            parent = cur;
            cur = cur.right;
        } else if (cur.val > key) { // 当前值大于目标值,移动到左子树
            parent = cur;
            cur = cur.left;
        } else { // 找到目标节点
            removeNode(parent, cur); // 调用辅助方法删除节点
            return; // 删除节点后退出方法
        }
    }
}

private void removeNode(TreeNode parent, TreeNode cur) {
    if (cur.right == null) { // 当前节点没有右子树
        if (cur == root) { // 当前节点是根节点
            root = root.left; // 根节点指向左子树
        } else if (parent.left == cur) { // 当前节点是父节点的左子节点
            parent.left = cur.left; // 父节点左子节点指向当前节点的左子树
        } else { // 当前节点是父节点的右子节点
            parent.right = cur.left; // 父节点右子节点指向当前节点的左子树
        }
    } else if (cur.left == null) { // 当前节点没有左子树
        if (cur == root) { // 当前节点是根节点
            root = root.right; // 根节点指向右子树
        } else if (parent.left == cur) { // 当前节点是父节点的左子节点
            parent.left = cur.right; // 父节点左子节点指向当前节点的右子树
        } else { // 当前节点是父节点的右子节点
            parent.right = cur.right; // 父节点右子节点指向当前节点的右子树
        }
    } else { // 当前节点有两个子节点
        TreeNode targetParent = cur; // 目标节点的父节点初始化为当前节点
        TreeNode target = cur.right; // 目标节点初始化为当前节点的右子节点
        // 寻找右子树中的最左节点
        while (target.left != null) {
            targetParent = target;
            target = target.left;
        }
        cur.val = target.val; // 用右子树中最左节点的值替换当前节点的值
        // 调整指针以删除目标节点
        if (targetParent.left == target) {
            targetParent.left = target.right;
        } else {
            targetParent.right = target.right;
        }
    }
}

——这里我们给每一条代码都加上了注释,读者可以根据注释来对上述代码进行理解!!!

这样我们就了解了二叉搜索树中常用的操作了.

3.二叉树的应用场景

        学习完二叉树的概念以及其基本的使用之后,让我们来学习一些二叉树的应用场景,二叉树(Binary Tree)在日常中有着广泛的应用。以下是一些主要的实际应用场景:

1. 数据结构和算法

  • 二叉搜索树(BST):用于实现高效的搜索、插入和删除操作,时间复杂度平均为 O(log n)。

  • 平衡树(如AVL树、红黑树):这些是自平衡二叉搜索树,确保树的高度保持在 O(log n),从而提供高效的操作。

  • 堆(Heap):二叉堆用于实现优先队列。最大堆用于实现高效的最大值查找,最小堆用于最小值查找。

2. 数据库和文件系统

  • B树和B+树:这些是多路搜索树,常用于数据库索引和文件系统索引,以提高查询和检索的效率。

  • Trie树:一种多叉树,用于实现前缀匹配,常用于字典存储和自动补全功能。

3. 图形和游戏开发

  • 四叉树和八叉树:用于空间分割,以提高碰撞检测、渲染和其他空间查询操作的效率。

  • 场景图(Scene Graph):在3D图形引擎中,场景图是一个树状结构,用于管理和渲染场景中的对象。

这样我们就大致的了解了二叉树在今后的日常中有哪些用武之地了!!!


以上就是本篇文章的主要内容了!!!

标签:right,Java,cur,parent,二叉,搜索,节点,left
From: https://blog.csdn.net/2302_80198073/article/details/140767638

相关文章

  • Java中的常见类(API)---java基础的五弹
    文章目录Java基础知识全解第五弹常用类一、String类1.判断功能的方法2.获取功能的方法3.转换功能的方法4.分割功能的方法5.其他常用方法二、StringBuilder1.字符串拼接2.StringBuffer3.StringBuilder三.Math类四.Random类五.System类六.包装类1.概述2.......
  • LeetCode - #107 二叉树的层序遍历 II
    文章目录前言1.描述2.示例3.答案关于我们前言我们社区陆续会将顾毅(Netflix增长黑客,《iOS面试之道》作者,ACE职业健身教练。)的Swift算法题题解整理为文字版以方便大家学习与阅读。LeetCode算法到目前我们已经更新到105期,我们会保持更新时间和进度(周一、......
  • Java基础第四弹-----多态、抽象类、接口和异常
    文章目录Java基础知识全解第四弹一、final1.概述2.使用场景3.总结二、继承中的构造方法三、前景知识1.Object2.toString()3.instanceof4.equals()四、多态1.多态定义2.多态条件3.两种转型方式3.1向上转型3.2向下转型4.为什么要转型五、抽象类1.定义2.格式3.抽象......
  • javadoc
    javadoc命令是用来生成自己API文档的参数信息@author作者名@version版本号@since指明需要最早使用的jdk版本@param参数名@return返回值情况@throws异常抛出情况packagecom.studen.base;/***@authorshudou*@version1.0*@since1.8*/publicclass......
  • Java初学-Day3
    一、数据类型(本期只讲基本数据类型)变量就是申请内存来存储值。也就是说,当创建变量的时候,需要在内存中申请空间。内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据。 因此,通过定义不同类型的变量,可以在内存中储存整数、小数或者字符。Jav......
  • 计算机毕业设计选题推荐-音乐播放系统-Java/Python项目实战
    ✨作者主页:IT毕设梦工厂✨个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。☑文末获取源码☑精彩专栏推荐⬇⬇⬇Java项目Python项目安卓项目微信小程序项目......
  • JAVA小白学习日记Day12
    CSS定位1.定位属性 在CSS中,position属性用于指定元素在文档流中的定位方式。常用的取值包括:static:默认值,元素遵循正常的文档流布局,不受top、right、bottom、left属性的影响。relative:元素相对于其正常位置进行定位,通过top、right、bottom、left属性可以调整元素相......
  • Java面试题(容器)
    目录1、Java容器都有哪些?2、 Collection和Collections有什么区别3、List、Set、Map之间的区别是什么?4、 HashMap和Hashtable有什么区别?5、如何决定使用HashMap还是TreeMap?6、 说一下HashMap的实现原理?7、 ArrayList和LinkedList的区别是什么?8、 ......
  • DAY13 二叉树part01
     今日任务 二叉树的递归遍历(前中后)二叉树的迭代遍历(前中后)二叉树的统一迭代遍历二叉树的层序遍历(共十道题目)完成情况递归已掌握,代码略迭代前中手写一编,后和统一未学习层序遍历题目如下102.二叉树的层序遍历1/**2*Definitionforabinarytreenode.3*s......
  • 自学JavaScript(放假在家自学第一天)
    目录 JavaScript介绍分为以下几点1.1JavaScript是什么1.2JavaScript书写位置1.3Javascript注释1.4Javascript结束符1.5Javascript输入输出语法JavaScript(是什么?)是一种运行在客户端(浏览器)的编程语言,实现人机交互效果。2.作用(做什么?)网页特效(监听用户的......