当前位置: 首页 > news >正文

《数据结构:二叉搜索树(Binary Search Tree)》

《数据结构:二叉搜索树(Binary Search Tree)》

**作者的个人gitee**​​

作者的算法讲解主页▶️

每日一言:“人生如逆旅,我亦是行人。🌸🌸”


🔴一、二叉搜索树的概念

二叉搜索树(Binary Search Tree,BST)是一种特殊的二叉树,具有以下性质:

  • 若左子树不为空,则左子树上所有结点的值都小于等于根结点的值。
  • 若右子树不为空,则右子树上所有结点的值都大于等于根结点的值。
  • 左右子树也分别为二叉搜索树。
  • 二叉搜索树中可以支持插入相等的值,也可以不支持,具体取决于使用场景的定义。如,在C++标准模板库中,mapset不支持插入相等值,而multimapmultiset支持插入相等值。

🔴二、二叉搜索树的性能分析

二叉搜索树的性能主要取决于其高度。以下是不同情况下的性能分析:

情况高度增删查改时间复杂度
最优logNO(logN)
最差NO(N)
平均取决于插入顺序取决于插入顺序
  • 最优情况当二叉搜索树为完全二叉树或接近完全二叉树时,其高度为log2N。此时增删查改的时间复杂度为 O(log2N)。
  • 最差情况当二叉搜索树退化为单支树或类似单支时,其高度为N。此时增删查改的时间复杂度为O(N)。
  • 平均情况:在实际应用中,二叉搜索树的高度取决于插入数据的顺序。如果插入数据是随机的,那么平均情况下二叉搜索树的性能接近最优情况;但如果插入数据是有序的,那么二叉搜索树可能会退化为单支树,性能接近最差情况。

🔴三、二叉搜索树的操作

(一)插入

插入操作的步骤如下:

  1. 树为空:如果二叉搜索树为空,则直接创建一个新的结点,并将其赋值给根指针。
  2. 树不为空:从根结点开始,按照二叉搜索树的性质进行比较:
    • 如果插入值小于当前结点的值,则向左子树移动。
    • 如果插入值大于当前结点的值,则向右子树移动。
    • 如果插入值等于当前结点的值(支持插入相等值的情况),可以选择向左或向右移动,但需要保持逻辑一致性。
  3. 找到空位置:当找到一个空位置时,创建一个新的结点,并将其插入到该位置。

(二)查找

查找操作的步骤如下:

  1. 从根开始:从根结点开始,将目标值与当前结点的值进行比较。
  2. 比较并移动
    • 如果目标值小于当前结点的值,则向左子树移动。
    • 如果目标值大于当前结点的值,则向右子树移动。
  3. 查找结果
    • 如果在某个结点找到目标值,则返回该结点。
    • 如果走到空结点仍未找到目标值,则说明目标值不存在。

(三)删除

删除操作相对复杂,需要分情况处理:

  1. 查找目标结点:首先查找要删除的结点是否存在。如果不存在,则返回false
  2. 删除目标结点:如果目标结点存在,根据其子树情况分以下四种情况处理:
    • 情况1:目标结点左右孩子均为空。
      • 直接删除该结点,并将其父结点对应的孩子指针置为空。
    • 情况2:目标结点左孩子为空,右孩子不为空。
      • 将目标结点的父结点对应的孩子指针指向目标结点的右孩子,然后删除目标结点。
    • 情况3:目标结点右孩子为空,左孩子不为空。
      • 将目标结点的父结点对应的孩子指针指向目标结点的左孩子,然后删除目标结点。
    • 情况4:目标结点左右孩子均不为空。
      • 使用替换法删除。可以找目标结点左子树的最大值结点(最右结点)或者右子树的最小值结点(最左结点)替代目标结点。替代后,将问题转化为删除替代结点(替代结点符合情况2或情况3,可以直接删除)。

🔴四、二叉搜索树的实现代码

(一)结构体BSTNode

template<classK>structBSTNode{K _key;BSTNode<K>*_left;BSTNode<K>*_right;BSTNode(constK&key):_key(key),_left(nullptr),_right(nullptr){}};

(二)类BSTree

template<classK>classBSTree{typedefBSTNode<K>Node;public:boolInsert(constK&key){if(_root==nullptr){_root=newNode(key);returntrue;}Node*parent=nullptr;Node*cur=_root;while(cur){if(cur->_key<key){parent=cur;cur=cur->_right;}elseif(cur->_key>key){parent=cur;cur=cur->_left;}else{returnfalse;// 不允许插入重复值}}cur=newNode(key);if(parent->_key<key){parent->_right=cur;}else{parent->_left=cur;}returntrue;}boolFind(constK&key){Node*cur=_root;while(cur){if(cur->_key<key){cur=cur->_right;}elseif(cur->_key>key){cur=cur->_left;}else{returntrue;// 找到目标值}}returnfalse;// 未找到目标值}boolErase(constK&key){Node*parent=nullptr;Node*cur=_root;while(cur){if(cur->_key<key){parent=cur;cur=cur->_right;}elseif(cur->_key>key){parent=cur;cur=cur->_left;}else{// 情况1:左右孩子均为空if(cur->_left==nullptr&&cur->_right==nullptr){if(parent==nullptr){_root=nullptr;}else{if(parent->_left==cur)parent->_left=nullptr;elseparent->_right=nullptr;}deletecur;returntrue;}// 情况2:左孩子为空,右孩子不为空elseif(cur->_left==nullptr){if(parent==nullptr){_root=cur->_right;}else{if(parent->_left==cur)parent->_left=cur->_right;elseparent->_right=cur->_right;}deletecur;returntrue;}// 情况3:右孩子为空,左孩子不为空elseif(cur->_right==nullptr){if(parent==nullptr){_root=cur->_left;}else{if(parent->_left==cur)parent->_left=cur->_left;elseparent->_right=cur->_left;}deletecur;returntrue;}// 情况4:左右孩子均不为空else{Node*rightMinP=cur;Node*rightMin=cur->_right;while(rightMin->_left){rightMinP=rightMin;rightMin=rightMin->_left;}cur->_key=rightMin->_key;if(rightMinP->_left==rightMin)rightMinP->_left=rightMin->_right;elserightMinP->_right=rightMin->_right;deleterightMin;returntrue;}}}returnfalse;// 未找到目标值}voidInOrder(){_InOrder(_root);cout<<endl;}private:void_InOrder(Node*root){if(root==nullptr){return;}_InOrder(root->_left);cout<<root->_key<<" ";_InOrder(root->_right);}Node*_root=nullptr;};

🔴五、二叉搜索树的应用场景

(一)key搜索场景

在key搜索场景中,二叉搜索树仅存储关键码(key),用于判断某个值是否存在。

  • 小区无人值守车库:将买了车位的业主车牌号录入后台系统,车辆进入时扫描车牌号,判断其是否存在于系统中,从而决定是否抬杆。
  • 英文单词拼写检查:将词库中的所有单词放入二叉搜索树,读取文章中的单词,查找其是否存在于二叉搜索树中,若不存在则提示拼写错误。

(二)key/value搜索场景

在key/value搜索场景中,二叉搜索树的每个结点不仅存储关键码(key),还存储与之对应的值(value)。搜索时以key为关键字进行比较,可以快速找到key对应的value。

  • 中英互译字典:在树的结点中存储英文单词(key)和对应的中文翻译(value),搜索时输入英文单词,即可找到其对应的中文翻译。
  • 商场无人值守车库:入口进场时扫描车牌号,记录车牌号和入场时间(key/value),出口离场时扫描车牌号,查找入场时间,计算停车时长和费用。
  • 统计文章中单词出现次数:读取一个单词,查找其是否存在于二叉搜索树中,若不存在则插入该单词并将其出现次数初始化为1,若存在则将其对应的出现次数加1。

🔴六、总结

二叉搜索树是一种重要的数据结构,具有插入、查找、删除等操作。其性能在最优情况下接近O(log2N),但在最差情况下会退化为O(N)。为了提高二叉搜索树的性能,后续可以学习其进阶,如平衡二叉搜索树(AVL树)、B树和红黑树。


车库**:入口进场时扫描车牌号,记录车牌号和入场时间(key/value),出口离场时扫描车牌号,查找入场时间,计算停车时长和费用。

  • 统计文章中单词出现次数:读取一个单词,查找其是否存在于二叉搜索树中,若不存在则插入该单词并将其出现次数初始化为1,若存在则将其对应的出现次数加1。

🔴六、总结

二叉搜索树是一种重要的数据结构,具有插入、查找、删除等操作。其性能在最优情况下接近O(log2N),但在最差情况下会退化为O(N)。为了提高二叉搜索树的性能,后续可以学习其进阶,如平衡二叉搜索树(AVL树)、B树和红黑树。


如果有帮助的话麻烦点个赞和关注吧,秋梨膏QAQ!

http://www.jsqmd.com/news/595120/

相关文章:

  • OpenClaw+千问3.5-9B开发辅助:自动生成代码与测试用例
  • 零基础玩转DAMO-YOLO:手把手教你搭建赛博朋克风目标检测系统
  • Linux 的 logname 命令
  • OpenClaw+Phi-3-vision-128k-instruct:跨境电商的商品主图自动优化方案
  • ddsad
  • MiniMax Skills 技能体系分析
  • 嵌入式开发调试宏的高级应用与优化技巧
  • OpenClaw日志分析:Qwen3-4B驱动的错误模式识别与解决方案
  • 山东大学创新实训项目个人博客——第一篇
  • 云原生核心技术科普文档
  • CentOS系统kernel:do_IRQ报错分析与实战解决方案
  • OpenClaw云端服务器搭建指南:2026年部署、配置大模型百炼APIKey、集成Skill超详细流程
  • SEN63C多参数环境传感器硬件连接与Arduino/ESP32驱动详解
  • **唐山急售二手房背后的市场密码与购房者机遇****一、唐山二手房市场的现状与急售现象的普遍性**近年来,唐山房地产市场经历了一系列的波动。根据相关数据显示,在过去的五年里,唐山的房价整体呈现
  • 零基础玩转OpenClaw:Qwen3.5-9B-AWQ-4bit图像问答机器人
  • Windows下OpenClaw安装指南:快速对接Qwen2.5-VL-7B多模态模型
  • C# System.Char 超全速查表 + 可直接复制代码
  • 互联网大厂Java求职面试全解析:从核心语言到微服务实战
  • 救命!这些毕设太好抄了,3000+毕设案例推荐第1016期
  • 企业应如何将SEO和SEM结合起来
  • OpenClaw+千问3.5-9B:3种文件自动归类方案对比
  • 放假给大家推荐一些孩子的资料,有了这些资源简直太好了!
  • OpenClaw+Phi-3-vision-128k-instruct:智能相册的自动化分类与标签系统
  • 照明灯具知识查询工具——您身边的光学专家
  • 救命!这些毕设太好抄了,3000+毕设案例推荐第1017期
  • 简单的kail中使用docker搭建vulhub靶场
  • OpenClaw自动化周报:Kimi-VL-A3B-Thinking多源数据汇总与分析
  • 北海哪家店的美食排队最长
  • 2026年花洒产品推荐:四款热门花洒横评,闭眼入不踩雷
  • OpenClaw多端控制方案:Qwen3-14b_int4_awq任务在手机与电脑间同步