新闻详情

新闻详情

首页 / 资讯中心 / 详情

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

发布时间:2026/10/1 11:36:33来源:尧图网络
数据结构 ----- 二叉搜索树
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旋转 变色
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

DeepSeek本地部署实战:Ollama+Dify打造私有知识库 2026/10/1 13:04:29

DeepSeek本地部署实战:Ollama+Dify打造私有知识库

1. 本地部署难点拆解:这次到底要搭什么折腾了两天,终于把 DeepSeek 本地部署这套流程跑通了。整体链路其实不复杂:Ollama 负责把大模型在本地跑起来,再用 Dify 接一个知识库,让模型回答问题时能引用自己的文档。这篇文…

阅读更多 →
Unity开发月度精选:水墨Shader、Burst优化与微信小游戏打包实战 2026/10/1 13:04:23

Unity开发月度精选:水墨Shader、Burst优化与微信小游戏打包实战

1. 为什么每月整理Unity项目这件事值得认真做 做Unity开发这些年,我养成了一个习惯:每个月固定花两三天时间,把近期社区里讨论度比较高、完成度也比较扎实的Unity项目过一遍。不是为了追热点,而是因为Unity这个生态太特殊了——它…

阅读更多 →
CAS-ViT实战复现:卷积加性注意力如何让图像分类提速降本 2026/10/1 13:04:23

CAS-ViT实战复现:卷积加性注意力如何让图像分类提速降本

简介:CAS-ViT实战项目面向图像分类任务,聚焦视觉Transformer计算效率与性能的平衡。CAS-ViT通过卷积加性标记混合器(CATM)和加性相似度函数,替代传统自注意力机制,显著降低计算开销,特别适合资源…

阅读更多 →
Logstash HTTP 413 错误排查:从现象到解决全攻略 2026/10/1 13:04:23

Logstash HTTP 413 错误排查:从现象到解决全攻略

1. 现象与误判:413 并不总是 Logstash 自己报的先说结论:Logstash 调用里出现 413,绝大多数情况下不是 Logstash 自身主动拒绝,而是某个中间环节认为请求体超过了它能接受的上限。HTTP 状态码 413 的定义就是 Payload Too Large&a…

阅读更多 →
可变形注意力详解:从DETR加速到DAT与DCNv3的机制实现 2026/10/1 13:04:23

可变形注意力详解:从DETR加速到DAT与DCNv3的机制实现

可变形注意力(Deformable Attention)这个概念我第一次认真啃,是在2020年复现DETR的那段时间。当时DETR要在整张特征图上做密集注意力,500个epoch才收敛到一个能看的精度,一个实验排期就是好几天,调一次参数…

阅读更多 →
Godot 4.7 用颜色贴图驱动场景物体散布:从原理到性能优化 2026/10/1 13:04:23

Godot 4.7 用颜色贴图驱动场景物体散布:从原理到性能优化

在游戏开发里,手动摆放植被、石头、道具这类重复性工作,做过的都懂——几百上千个物件一个个拖进场景,调位置、调旋转、调缩放,眼睛都快看瞎了,改一次地形还得全部重来。我最近在 Godot 4.7 里折腾出一套用地面 UV 贴图…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉