数据结构奇妙旅程之二叉平衡树

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱
ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转载还请通知˶⍤⃝˶
个人主页:xiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
系列专栏:xiaoxie的JAVA系列专栏——CSDN博客●'ᴗ'σσணღ*
我的目标:"团团等我💪( ◡̀_◡́ ҂)" 

( ⸝⸝⸝›ᴥ‹⸝⸝⸝ )欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​+关注(互三必回)!

一.二叉平衡树

1.二叉平衡树的概念

二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:

若它的左子树不为空,则左子树上所有节点的值都小于根节点的值

若它的右子树不为空,则右子树上所有节点的值都大于根节点的值

它的左右子树也分别为二叉搜索树

从上述概念以及图中可以看出,二叉搜索树具有以下特性:

1. 二叉搜索树中最左侧的节点是树中最小的节点,最右侧节点一定是树中最大的节点

2. 采用中序遍历遍历二叉搜索树,可以得到一个有序的序列 

2.二叉搜索树的主要操作

1. 查询

2.插入

1.插入的为一颗空树

直接插入即可

2.. 如果树不是空树,按照查找逻辑确定插入位置,插入新结点

根据二叉搜索树的性质插入节点,"左小右大"

  1. 对于树中的任意节点 n,其左子树中的所有节点的值都小于 n 的值,其右子树中的所有节点的值都大于 n 的值。
  2. 在插入新节点时,需要按照二叉搜索树的性质找到合适的位置插入,保持树的有序性。
  3. 插入节点后,需要调整树的结构,保证树仍然是一个二叉搜索树。

3.删除

假设删除节点cur那么cur有以下几种情况

1.cur 的左孩子为空,右孩子不为空,

2.cur 的右孩子为空,左孩子不为空.

3.cur 的左右孩子均为空.

4.cur 的左右孩子均不为空.

接下来博主将会通过画图的形式来演示这四种情况该如何删除节点

1.cur 的左孩子为空,右孩子不为空

 2.cur 的右孩子为空,左孩子不为空.

3. cur 的左右孩子均为空.

4. cur 的左右孩子均不为空.

1.假设我们需要删除节点70,我们首先需要通过遍历二叉搜索树,找到70这个节点的对应位置.

2.我们发现70这个节点,左右孩子均不为空,这个时候就不可以通过简单的删除就可以了,我们需要用到替换法,即在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被 删除节点中,再来处理该结点的删除问题.

2.1这里解释一下为什么是在它的右子树中寻找中序下的第一个结点(关键码最小),当需要删除一个节点时,如果该节点有右子树,则可以在右子树中找到中序遍历下的第一个节点(即右子树中最小的节点)来替代当前节点。这是因为右子树中的所有节点都大于当前节点,而右子树中最小的节点又小于右子树中的所有其他节点,所以用右子树中的最小节点来替代当前节点可以保持二叉搜索树的性质不变。

3.找到"替罪羊"节点 t 后我们就需要把要删除的节点cur使他的值等于t .

4.最后删除节点t即可.

4.二叉搜索树基本操作的Java代码实现

public class BinarySearchTree {
    public static class TreeNode {
        public TreeNode left;
        public TreeNode right;
        public int val;
        public TreeNode(int val) {
            this.val = val;
        }
    }
    public TreeNode root;
    /**
     * 查询节点是否存在
     * @author xiaoxie
     * @date 2024/3/6 10:44
     * @param val
     * @return boolean
     */
    public boolean search(int val) {
        if(root == null) {
            System.out.println();
            return false;
        }
        TreeNode cur = root;
        while (cur != null) {
            if(val < cur.val) {
                cur = cur.left;
            } else if (val > cur.val) {
                cur = cur.right;
            }else {
                System.out.println("找到了");
                return true;
            }
        }
        System.out.println("该节点"+val+"不存在");
        return false;
    }
    /**
     * 插入节点
     * @author xiaoxie
     * @date 2024/3/6 10:47
     * @param val
     */
    public void insertTreeNode(int val) {
        TreeNode node = new TreeNode(val);
        if(root == null) {
            root = node;
            return;
        }
        TreeNode parent = null;
        TreeNode cur = root;
        while (cur != null) {
            if(node.val < cur.val) {
                parent = cur;
                cur = cur.left;
            } else if (node.val > cur.val) {
                parent = cur;
                cur = cur.right;
            }else {
                System.out.println("节点值 " + val + " 已经存在于树中,不进行插入操作");
                return;
            }
        }
        //cur = null
        if(node.val < parent.val) {
            parent.left = node;
        }else {
            parent.right = node;
        }
    }
    /**
     * 删除节点
     * 可以使用替罪羊的方法来实现
     * @author xiaoxie
     * @date 2024/3/6 12:15
     * @param val
     * @return boolean
     */
    public boolean remove(int val) {
        //首先先找到是哪一个节点
        if(root == null) {
            return false;
        }
        TreeNode parent = null;
        TreeNode cur = root;
        while (cur != null) {
            if(cur.val > val) {
                parent = cur;
                cur = cur.left;
            } else if (cur.val < val) {
                parent = cur;
                cur = cur.right;
            }else {
                break;
            }
        }
        //cur == null 说明要删除的节点不在二叉搜索树上
        if(cur == null) {
            return false;
        }
        // cur有多种情况
        //1.cur 没有左右孩子
        //2.cur 只有左孩子
        //3.cur 只有右孩子

        //4.cur 有左右孩子 -- 需要使用替罪羊的方法来删除
        if(cur.right != null && cur.left != null) {
            TreeNode t = cur.right;
            TreeNode tp = cur;
            while (t.left != null) {
                tp = t;
                t = t.left;
            }
            cur.val = t.val;//使要删除的节点的值等于替罪羊节点
            //删除替罪羊节点
            if(tp.left == t) {
                tp.left = t.right;
            }else {//出现tp.right = t 的情况,t节点一开始就是叶子节点
                tp.right = t.right;
            }
        }else {
            //cur 只有右孩子
            if(cur.left == null && cur.right != null){
                if(parent == null) {
                    root = cur.right;
                }else {
                    if(parent.val < cur.val) {
                        parent.right = cur.right;
                    }else {
                        parent.left = cur.right;
                    }
                }
            }//cur 只有左孩子
            else if (cur.left != null && cur.right == null) {
                if(parent == null) {
                    root = cur.left;
                }else {
                    if(parent.val < cur.val) {
                        parent.right = cur.left;
                    }else {
                        parent.left = cur.left;
                    }
                }
            }
            //cur 没有左右孩子
            else  {
                if(parent == null) {
                    root = null;
                }else {
                    if(parent.val < cur.val) {
                        parent.right = null;
                    }else {
                        parent.left = null;
                    }
                }
            }
        }
        return true;
    }

 5.性能分析

插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。 对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的深度 的函数,即结点越深,则比较次数越多。 但对于同一个关键码集合,如果各关键码插入的次序不同,可能得到不同结构的二叉搜索树:

1.最优情况下,二叉搜索树为完全二叉树

其平均比较次数为:log N;

2.最差情况下,二叉搜索树退化为单支树

 其平均比较次数为: 2 / N

问题:如果退化成单支树,二叉搜索树的性能就失去了。那能否进行改进,不论按照什么次序插入关键码,都可以 是二叉搜索树的性能最佳?

那就需要用到AVL树了通过旋转来使二叉搜索树变成完全二叉树的形式,这里博主就不过多的赘述了,如果感兴趣,可以为博主点上一个关注,在下一篇文章中,博主将详细解读AVL树

感谢你的阅读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/445080.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构入门篇 之 【单链表】的实现讲解(附单链表的完整实现代码以及用单链表完成通讯录的实现代码)

虽然封面是顶针&#xff0c;但是我们还是要好好学习❀ 一.单链表 1.单链表的概念 2.单链表的结构 3.单链表的实现 1&#xff09;.尾插函数 SLTPushBack 2&#xff09;.打印函数 SLPrint 3&#xff09;. 头插函数 SLTPushFront 4&#xff09;.尾删函数 SLTPopBack 5&am…

docker容器的数据卷

1配置数据卷 docker run --namen01 -d --restartalways -p 80:80 -v /qy172/data/nginx/html:/usr/share/nginx/html nginx 2Docker应用部署 1搜索mysql镜像 docker search mysql 2拉取mysql镜像 docker pull mysql:5.6 3创建容器&#xff0c; 设置端口映射、目录映射 d…

Pycharm安装,环境初次配置与运行第一个简单程序

一、Pycharm安装 1.在PyCharm官网中&#xff0c;找到社区版下载链接&#xff0c;下载Pycharm社区版&#xff0c;社区版免费 2.下载成功后&#xff0c;双击下载好的安装包&#xff0c;点击下一步后&#xff0c;点击“浏览”更改安装路径到C盘以外其他硬盘&#xff0c;点击“下…

6 种 卷积神经网络压缩方法

文章目录 前言 1、低秩近似 2、剪枝与稀疏约束 3、参数量化 4、二值化网络 &#xff08;1&#xff09;二值网络的梯度下降 &#xff08;2&#xff09;两个问题 &#xff08;3&#xff09;二值连接算法改进 &#xff08;4&#xff09;二值网络设计注意事项 5、知识蒸馏 6、浅层 …

Pulsar 社区周报 | No.2024.03.08 Pulsar-Spark Connector 助力实时计算

关于 Apache Pulsar Apache Pulsar 是 Apache 软件基金会顶级项目&#xff0c;是下一代云原生分布式消息流平台&#xff0c;集消息、存储、轻量化函数式计算为一体&#xff0c;采用计算与存储分离架构设计&#xff0c;支持多租户、持久化存储、多机房跨区域数据复制&#xff0c…

SpringCloudGateway理论与实践

文章目录 网关介绍为什么需要网关Gateway 使用gateway pom依赖yml 配置重启测试总结 断言过滤器工厂路由过滤器的种类请求头过滤器默认过滤器全局过滤器总结 Gateway解决跨域 网关介绍 Spring Cloud Gateway 是一个基于Spring Framework 5&#xff0c;由Spring Cloud团队开发的…

定制repo(不再切换python和google源)

文章目录 定制repo&#xff08;不再切换python和google源&#xff09;前言各用各的repo定制repo2/repo3源码自动识别repo2/repo3项目完整解决方案&#xff1a; 定制repo&#xff08;不再切换python和google源&#xff09; 众知&#xff0c;Android/AOSP/ROM系统开发&#xff0c…

垃圾回收:JavaScript内存管理的利器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【SpringCloud】微服务重点解析

微服务重点解析 1. Spring Cloud 组件有哪些&#xff1f; 2. 服务注册和发现是什么意思&#xff1f;Spring Cloud 如何实现服务注册和发现的&#xff1f; 如果写过微服务项目&#xff0c;可以说做过的哪个微服务项目&#xff0c;使用了哪个注册中心&#xff0c;常见的有 eurek…

vue实现购物车功能

实现功能 CSS部分 <style>.tr {display: flex;}.th {margin: 10px;width: 20%;height: 50%;}.td {display: flex;margin: 10px;width: 20%;height: 100px;align-items: center;}.app-container .banner-box {border-radius: 20px;overflow: hidden;margin-bottom: 10px;}…

docker-swarm集群搭建

目录 一、docker swarm介绍 二、部署docker 三、搭建集群 3.1 工作模式 3.2 将当前主机作为leader 3.3 将第二个节点slave1加入到worker 3.4 将第三个节点slave2也加入到worker 3.5 将第四个节点(slave3)加入到manager 四、总结 一、docker swarm介绍 Docker Swarm…

CSS顶部与JS后写:网页渲染的奥秘

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

动态规划(算法竞赛、蓝桥杯)--数位DP度的数量

1、B站视频链接&#xff1a;E38 数位DP 度的数量_哔哩哔哩_bilibili #include <bits/stdc.h> using namespace std; const int N34; int a[N];//把B进制数的每一位抠出存入数组 int f[N][N];//f[i][j]表示在i个位置上&#xff0c;放置j个1的组合数 int K,B;void init(…

11.Node.js入门

一.什么是 Node.js Node.js 是一个独立的 JavaScript 运行环境&#xff0c;能独立执行 JS 代码&#xff0c;因为这个特点&#xff0c;它可以用来编写服务器后端的应用程序 Node.js 作用除了编写后端应用程序&#xff0c;也可以对前端代码进行压缩&#xff0c;转译&#xff0c;…

Java 数据结构之链表

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if (headA null || headB null) return null;ListNode pA headA, pB headB;while (pA ! pB) {pA pA null ? headB : pA.next;pB pB null ? headA : pB.next;}return pA;} public ListNode rev…

2024.3.6每日一题

LeetCode 找出数组中的 K -or 值 题目链接&#xff1a;2917. 找出数组中的 K-or 值 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 nums 中的 K-or 是一个满足以下条件的非负整数&#xff1a; 只有在 nums 中&…

【开源】SpringBoot框架开发教学资源共享平台

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课程资源模块2.4 课程作业模块2.5 课程评价模块 三、系统设计3.1 用例设计3.2 类图设计3.3 数据库设计3.3.1 课程档案表3.3.2 课程资源表3.3.3 课程作业表3.3.4 课程评价表 四、系统展…

遗传算法GA求解机器人栅格地图最短路径规划,可以自定义地图及起始点(提供MATLAB代码)

一、原理介绍 遗传算法是一种基于生物进化原理的优化算法&#xff0c;常用于求解复杂问题。在机器人栅格地图最短路径规划中&#xff0c;遗传算法可以用来寻找最优路径。 遗传算法的求解过程包括以下几个步骤&#xff1a; 1. 初始化种群&#xff1a;随机生成一组初始解&…

先进电机技术 —— 高速电机与低速电机

一、背景 高速电机是指转速远高于一般电机的电动机&#xff0c;通常其转速在每分钟几千转至上万转甚至几十万转以上。这类电机具有功率密度高、响应速度快、输出扭矩大等特点&#xff0c;在航空航天、精密仪器、机器人、电动汽车、高端装备制造等领域有着广泛的应用。 高速电…

【Pytorch】新手入门:基于sklearn实现鸢尾花数据集的加载

【Pytorch】新手入门&#xff1a;基于sklearn实现鸢尾花数据集的加载 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望…