【数据结构】二叉搜索树

【数据结构】二叉搜索树

数据结构系列五:Map与Set(三)

二叉搜索树

一、搜索原理(有序维护)

1.插入

2.删除

2.1单子树节点

2.2双子树节点

二、搜索性能

1.排成完全二叉树

2.排成链表


二叉搜索树

每个节点都经过 整体搜索比较排维护组成的有序树是二叉排序树,即二叉搜索树

一、搜索原理(有序维护)

依据维护成的整体有序性左右分位判相对位置对整体搜完来确定序位进而持续维护 有序树的整体有序性(中序遍历),具体要求在:

1.插入

插入元素时,要搜索确定完 在路径下的所有节点的相对位置后 再插入,才可确保 插入在整体下的有序维护性,所以所有的元素插入 都是插到路径末 整体树的子叶节点 空位置进行的

插入代码 

 public boolean insert(int val) { TreeNode node = new TreeNode(val); if(root == null) { root = node; return true; } TreeNode cur = root; TreeNode parent = null; //搜索到 路径末叶节点 空位置上 插入,确保能维护 元素插入的整体有序 while (cur != null) { if(cur.val <val) { parent = cur; cur = cur.right; }else if(cur.val > val) { parent = cur; cur = cur.left; }else { return false; } } if(parent.val < val) { parent.right = node; }else { parent.left = node; } return true; } 

2.删除

删除节点,要维护 节点删完后 节点的子树在整体里能重新有序性

2.1单子树节点

如果删除节点 只有一棵子树,直接绕删此节点 连其子树,删除后 是维护着子树 进整体重新有序的


2.2双子树节点

如果删除节点 有两棵子树,找到子树中的 最上最端的 最值单子树节点,(左子树最右端最大,右子树最左端最小用子树的最值 往上覆盖掉 以删掉节点值,接着用单子树直接绕删的方式 删此已重复值的单子树节点 完成节点删除后 两子树重新能融整体 有序维护的删除

删除代码 

 public void remove(int val) { TreeNode cur = root; TreeNode parent = null; while (cur != null) { if(cur.val <val) { parent = cur; cur = cur.right; }else if(cur.val > val) { parent = cur; cur = cur.left; }else { //删除的逻辑 removeNode(parent,cur); return; } } } private void removeNode(TreeNode parent,TreeNode cur) { //本质 ——> 单子树节点的删除,直接 绕删转去连 它的那棵单子树就行了 //处理本质 绕删连都是相同的,但在具体操作时 面对的情况上 有点不同,要分着处理 //1.删除单子树节点 //1.1要删的单子树节点 左边没有树 if(cur.left == null) { //1.1.1要删除的单子树节点 没有父母parent==null,在操作上有点不同,父节点空情况要防空 分开来处理操作 if(cur == root) { root = cur.right; //1.1.2要删除的单子树节点 有父母 在父节点左边,要用父节点的左边去绕连 }else if(cur == parent.left) { parent.left = cur.right; //1.1.3要删除的单子树节点 有父母 在父节点右边,要用父节点的右边去绕连 }else { parent.right = cur.right; } //1.2要删的单子树节点 右边没有树 }else if(cur.right == null) { //1.2.1要删除的单子树节点 没有父节点,父节点空情况 分着处理它 if(cur == root) { root = cur.left; //1.2.2要删除的单子树节点 在父节点左边,要用父节点左边去绕连 }else if(cur == parent.left) { parent.left = cur.left; //1.2.3要删处的单子树节点 在父节点右边,要用父节点右边去绕连 }else { parent.right = cur.left; } //其实往一边找替罪羊去删的删法 也同样适用于 单子树节点的删除,往对应节点 对应的单子树那边 找替罪羊去删 同样也能完成,不过这里选择将它们分开来处理了 //2.删除双子树节点 }else { //统一用 往右子树找替罪羊的删法: TreeNode targetParent = cur; TreeNode target = cur.right; //2.1target.left==null,找到替罪羊 while (target.left != null) { targetParent = target; target = target.left; } //2.2最值往上覆盖删掉 要删除节点的值: cur.val = target.val; //2.3把替罪羊节点删除: //2.3.1如果替罪羊一上来 就直接在 要删除节点的右首节点,分成的情况就是 替罪羊节点在其父节点的右边的情况,要用父节点的右边去绕连删 if(target == targetParent.right) { targetParent.right = target.right; }else { //2.3.2替罪羊在要删除节点 首个右节点之后的,分成的情况就是 替罪羊在其父节点的左边 的一般情况,要用父节点的左边去绕连删 targetParent.left = target.right; } } } 
二、搜索性能

1.排成完全二叉树

左右均匀分配有序排 建成的搜索树每次的分查 都能排掉区域一半的数据搜索性能高,当分配均匀成 完全二叉树时,搜索的次数为 树的高度log(n) 就能查到数据


2.排成链表

单分支分配有序排成的搜索树 退化成链表每次的分查 都不能排额外数据搜索性能低下搜索的次数为 树的高度 为链表的长度n

Read more

Flutter 组件 http_interop 的适配 鸿蒙Harmony 实战 - 驾驭跨平台通讯互操作标准、实现鸿蒙端 HTTP 客户端深度解耦与协议中继方案

Flutter 组件 http_interop 的适配 鸿蒙Harmony 实战 - 驾驭跨平台通讯互操作标准、实现鸿蒙端 HTTP 客户端深度解耦与协议中继方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 http_interop 的适配 鸿蒙Harmony 实战 - 驾驭跨平台通讯互操作标准、实现鸿蒙端 HTTP 客户端深度解耦与协议中继方案 前言 在鸿蒙(OpenHarmony)生态的大型微服务矩阵集成、跨机构 API 网关桥接、以及需要在一个应用中同时引入多个依赖于不同网络库(如 dio, http, cronet)的三方组件开发中,“网络协议栈的互操作性(Interop)”是解决工程依赖地狱的终极武器。面对某些历史遗留的三方库硬编码了特定版本的请求 client。 如果我们无法实现对这些 client 的无感平替与标准化包装。那么不仅会导致在鸿蒙端产生多个冗余的网络连接池造成系统资源浪费。更会因为无法在全局层面注入统一的鉴权(Auth)与加密(Crypto)中间件,引发严重的合规性风险。 我们需要一种“接口中道、请求无间”的互操作艺术。 http_

By Ne0inhk

Flutter 三方库 http_status_code 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、严谨、工业级的网络响应审计与 HTTP 状态码语义化控制引擎

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 http_status_code 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、严谨、工业级的网络响应审计与 HTTP 状态码语义化控制引擎 在鸿蒙(OpenHarmony)系统的端云一体化网络库封装、政企级应用的网络错误诊断、或者是针对复杂的 REST API 全生命周期监听中,如何摆脱凌乱的 magic number(如 404, 500),转而使用具备自描述性、且完全符合 RFC 规范的语义化常量?http_status_code 为开发者提供了一套工业级的、基于标准定义的 HTTP 状态码枚举与描述查询方案。本文将深入实战其在鸿蒙网络安全架构中的应用。 前言 什么是 HTTP Status Code?它是 Web

By Ne0inhk
2025最新如何在本地部署 Stable Diffusion3.5超详细完整教程

2025最新如何在本地部署 Stable Diffusion3.5超详细完整教程

在本地部署 Stable Diffusion 3.5:让 AI 绘图更便捷 前言 随着人工智能的快速发展,图像生成技术日益成熟,Stable Diffusion 3.5 作为一款强大的 AI 绘图工具,广泛应用于设计师、创作者等人群的视觉内容生成。它能够通过文本提示生成高质量图像,且具备较高的可控性和细腻的生成效果。 然而,默认情况下,Stable Diffusion 3.5 仅能在局域网内运行,远程操作或者出门时调整参数、查看进度会受到限制。在本文中,我们将通过本地部署的方式,帮助您克服这一限制,实现更加灵活的使用。 提示:不同型号的 Stable Diffusion 对硬件要求有所不同。以 Large Turbo 版本为例,推荐配备至少 8GB 显存以保证流畅运行。 文章目录在本地部署 Stable Diffusion

By Ne0inhk
【Linux系统编程】(四十二)吃透线程互斥!从原理到实战,手把手教你玩转 Linux 下的互斥锁

【Linux系统编程】(四十二)吃透线程互斥!从原理到实战,手把手教你玩转 Linux 下的互斥锁

目录 前言 一、线程互斥的核心概念:搞懂这些,才算入门 1.1 共享资源与临界资源 1.2 临界区 1.3 互斥的定义 1.4 原子性:互斥的底层要求 二、多线程共享资源的坑:亲眼看看问题出在哪 2.1 问题代码:未加互斥的售票系统 2.2 编译运行与异常结果 2.3 问题根源:三步分析 (1)线程调度的随机性 (2)耗时操作放大了竞争问题 (3)ticket--本身不是原子操作 2.4 解决问题的核心要求 三、Linux 下的互斥量:mutex 的使用全解析 3.1 互斥量的类型与核心接口

By Ne0inhk