数据结构 ----- 二叉搜索树

发布时间:2026/10/1 11:36:48

数据结构 ----- 二叉搜索树 BSTAVL红黑树共性本质都是二叉搜索树都遵守BST规则中序遍历的结果都是升序有序序列节点结构都是二叉树节点数据域左指针右指针基础操作逻辑一致查找插入删除的查找路径一致区别主要在平衡约束强度。普通 BST 不保证平衡AVL 严格平衡查找快但增删旋转多红黑树弱平衡旋转少增删性能更好。AVL 和红黑树是在 BST 基础上增加平衡约束解决普通 BST 最坏退化成链表的缺陷。二叉搜索树BST核心规则左子树所有节点值 根节点值右子树所有节点值 根节点值左、右子树本身也都是 BST三大基础操作1.查找从根开始比较小于根去左子树大于根去右子树相等找到平均O()最坏:O(n)有序插入树退化成一条链表TreeNode* search(TreeNode* root, int key) { if (root nullptr || root-val key)return root; if (key root-val) { return search(root-left, key); } return search(root-right, key); }2.插入与查找的逻辑一致新节点一定是叶子节点TreeNode* insert(TreeNode* root, int val) { if (root nullptr)return new TreeNode(val); if (val root-val) { root-left insert(root-left, val); } else if (val root-val) { root-right insert(root-right, val); } return root; }3.删除删除难点分 3 种情况叶子节点直接删除只有左孩子 / 只有右孩子用子节点替换当前节点左右孩子都存在两种选择取右子树的最小值右子树最左节点替换当前节点再删掉这个最小节点或者取左子树的最大值左子树最右节点替换当前节点再删掉该节点TreeNode* remove(TreeNode* root, int key) { if (root nullptr)return nullptr; if (key root-val) { root-left remove(root-left, key); } else if (key root-val) { root-right remove(root-right, key); } else { if (!root-left) { TreeNode* tmp root-right; delete root; return tmp; } if(!root-right) { TreeNode* tmp root-left; delete root; return tmp; } TreeNode* minParent nullptr; TreeNode* cur getMinAndParent(root-right,minParent); if (minParent nullptr) root-right cur-right; else minParent-left cur-right; cur-left root-left; cur-right root-right; delete root; return cur; } return root; }TreeNode* getMinAndParent(TreeNode* root, TreeNode* parent) { parent nullptr; while (root-left ! nullptr) { parent root; // 记录当前节点作为父 root root-left; } return root; // root停在最左就是最小值节点 }关于情况三关键是要断掉cur与树的联系所以要提前保存cur的父节点以免出现野指针AVL平衡二叉搜索树AVL 树 BST 平衡约束平衡因子 BF 左子树高度 − 右子树高度AVL 强制要求每个节点的平衡因子只能是 -1、0、1如果 (|BF|1) → 树失衡需要旋转修复目的限制树高保证查找 / 插入 / 删除 时间复杂度 O (logn)不会退化成链表普通 BST 最坏 O (n)结点结构struct TreeNode { int val; TreeNode *left; TreeNode *right; int height; // AVL独有记录以当前节点为根的子树高度 TreeNode(int v) : val(v), left(nullptr), right(nullptr), height(1){} };四种失衡情况LL左左右旋在失衡节点的左子树的左孩子处插入左子树过重此时为AVL树插入1根节点平衡因子为2失衡此时应该右旋把失衡节点的左孩子提上来作为新根左孩子原来的右子树变成失衡节点的左子树失衡节点变成其左孩子的右孩子代码:AVLNode* Right_Rotate(AVLNode* node) { AVLNode* child node-leftchild; AVLNode* grandchild child-rightchild; node-leftchild grandchild; child-rightchild node; //更新node和child的高度 Update_Height(node); Update_Height(child); return child;RR右右左旋失衡节点的右孩子 顶替失衡节点的位置右孩子提升为当前子树根失衡节点下沉变成其右孩子的左孩子T2 搬家右孩子原来的左子树 拿出来作为失衡节点的右子树AVLNode* Left_Rotate(AVLNode* node) { AVLNode* child node-rightchild; AVLNode* grandchild child-leftchild; node-rightchild grandchild; child-leftchild node; Update_Height(node); Update_Height(child); return child; }LR左-右左子树的右子树过重先左旋左孩子再右旋失衡点RL右-左右子树的左子树过重先右旋右孩子再左旋失衡点AVLNode* Rotate(AVLNode* node) { int ba Get_BalanceFactor(node); if (ba 2) { int cba Get_BalanceFactor(node-leftchild); if (cba 1) { Right_Rotate(node); }//LL单右旋 if (cba -1) { //先左旋再右旋 node-leftchild Left_Rotate(node-rightchild); } } int ba_right Get_BalanceFactor(node); if(ba_right- 2) { int cba_right Get_BalanceFactor(node-rightchild); if (cba_right-1){ return; }//RR单左旋 if (cba_right 1) { //先右旋再左旋 } } } //判断先左旋还是先右旋关键是看失衡节点左右孩子的平衡因子红黑树红黑树的特点红黑树是自平衡二叉搜索树 BST不是靠高度差约束靠 5 条颜色规则限制最长路径不超过最短路径 2 倍保证查找、插入、删除都是 O(logn)性质每个节点要么红色要么黑色。根节点一定是黑色。所有叶子节点NIL 空哨兵节点不是数据节点是黑色。红色节点的两个子节点一定都是黑色不能有连续红节点红不能连红。从任意一个节点到它所有后代 NIL 叶子的所有路径黑色节点数量相等→ 黑高相同。核心思想不强制左右高度差≤1只限制红节点分布。牺牲一点点查找效率大幅减少旋转次数。AVL 插入最多 2 次旋转红黑树删除最多 3 次旋转插入最多 2 次红黑树的插入插入新节点默认为红色然后向上回溯看是否违反了红连红规则叔叔节点是红色父、叔叔变黑祖父变红继续向上回溯。叔叔黑色LR / LL旋转 变色。叔叔黑色RL / RR旋转 变色
延伸阅读

更多相关文章

2026/10/1 11:36:48

BRD/MRD/PRD 本质是需求穿透三阶漏斗

简介:本资源是一份面向产品经理初学者与进阶从业者的专业文档资料,系统梳理商业需求文档(BRD)、市场需求文档(MRD)和产品需求文档(PRD)的核心定位、适用对象及协同逻辑。重点详解BRD…

2026/10/1 11:36:48

【流匹配模型Flow Maching】流匹配模型入门理解(2)

目录前言1. 模拟数据定义2. 构造训练路径3. 速度预测网络4. 训练5. 从噪声逐步生成6. 相同起点,一步与多步比较前言 之前已经介绍过DDMP以及流模型见如下四篇链接: 【扩散模型DDPM】扩散模型入门理解(1), 【扩散模型DDPM】扩散模…

2026/10/1 11:36:48

细胞衰老的核心密码:NAD+平衡状态决定人体机能的存续时长

细胞衰老的核心密码:NAD平衡状态决定人体机能的存续时长人体的器官衰老、体能衰退、机能下滑,所有老化表现的底层核心密码,都指向同一个物质:NAD。它不是普通的营养物质,是调控细胞代谢、修复、更新、维稳的核心辅酶&a…

2026/10/1 12:31:51

基于Spring Boot的废旧物资预约回收系统:毕设项目全链路解析

每年帮学生复审毕业设计的Java项目,我都会遇到同一类题目:基于Spring Boot的业务管理系统。这次拿到的“瑞回宝废旧物资预约回收系统”比较有代表性——题面是一个环保回收业务,背后却串联了Spring Boot后端开发从项目初始化、数据建模、状态…

2026/10/1 12:31:51

【C++入门】编译链接模型 - 02 预处理把头文件怎样塞进源文件

博主介绍:程序喵大人 35 - 资深C/C/Rust/Android/iOS客户端开发10年大厂工作经验嵌入式/人工智能/自动驾驶/音视频/游戏开发入门级选手《C20高级编程》《C23高级编程》等多本书籍著译者更多原创精品文章,首发gzh,见文末👇&#x…

2026/10/1 12:31:51

MessageBox深度解析:从API参数到封装与高阶应用

做桌面客户端开发这些年,我发现被问得最多的问题不是高深算法,而是 MessageBox(消息提示框)这种看起来人人都会的组件。同事拿着一段弹窗代码来找我:“这个确定按钮点下去,整个界面卡住不动了,到…

2026/10/1 12:31:51

QiLink

QiLink是道息实验室发起的全球首个开源协同协议体系,是整套“道息-气链”双螺旋架构的核心技术工具层,完全由徐玉生原创定义,是连接顶层东方哲学理念与实体产业落地的核心枢纽‌。🔍 名称的专属原创内涵它的命名本身就是独创语义的…

2026/10/1 5:21:14

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/9/29 21:48:03

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 10:48:55

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑