news 2026/4/23 11:54:49

【数据结构】二叉搜索树 C++ 简单实现:增删查改全攻略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【数据结构】二叉搜索树 C++ 简单实现:增删查改全攻略

二叉搜索树(Binary Search Tree, BST)的 C++ 简单实现
包含最常见的增、删、查、改操作,以及一些常用辅助函数。

以下代码尽量写得清晰、结构化,适合学习与理解。

#include<iostream>#include<queue>#include<vector>usingnamespacestd;// BST 节点定义structNode{intval;Node*left;Node*right;Node(intv):val(v),left(nullptr),right(nullptr){}};classBinarySearchTree{private:Node*root;// 辅助函数:递归插入Node*insertHelper(Node*node,intval){if(node==nullptr){returnnewNode(val);}if(val<node->val){node->left=insertHelper(node->left,val);}elseif(val>node->val){node->right=insertHelper(node->right,val);}// 相等时可以选择不插入(或覆盖/计数,此处选择不插入)returnnode;}// 辅助函数:查找节点(返回节点指针)Node*findHelper(Node*node,intval){if(node==nullptr||node->val==val){returnnode;}if(val<node->val){returnfindHelper(node->left,val);}else{returnfindHelper(node->right,val);}}// 辅助函数:找最小值节点(用于删除时找后继)Node*findMin(Node*node){while(node&&node->left){node=node->left;}returnnode;}// 辅助函数:删除节点(递归版)Node*removeHelper(Node*node,intval){if(node==nullptr){returnnullptr;}if(val<node->val){node->left=removeHelper(node->left,val);}elseif(val>node->val){node->right=removeHelper(node->right,val);}else{// 找到要删除的节点// 情况1:没有子节点(叶子)if(node->left==nullptr&&node->right==nullptr){deletenode;returnnullptr;}// 情况2:只有一个子节点elseif(node->left==nullptr){Node*temp=node->right;deletenode;returntemp;}elseif(node->right==nullptr){Node*temp=node->left;deletenode;returntemp;}// 情况3:有两个子节点 → 用右子树的最小节点替换else{Node*successor=findMin(node->right);node->val=successor->val;// 复制值node->right=removeHelper(node->right,successor->val);// 删除后继}}returnnode;}// 辅助函数:中序遍历(验证 BST 是否正确)voidinorderHelper(Node*node){if(node==nullptr)return;inorderHelper(node->left);cout<<node->val<<" ";inorderHelper(node->right);}// 销毁整棵树(析构函数调用)voiddestroyTree(Node*node){if(node==nullptr)return;destroyTree(node->left);destroyTree(node->right);deletenode;}public:BinarySearchTree():root(nullptr){}~BinarySearchTree(){destroyTree(root);}// 插入voidinsert(intval){root=insertHelper(root,val);}// 查找(是否存在)boolfind(intval){returnfindHelper(root,val)!=nullptr;}// 查找并返回节点指针(用于修改值)Node*findNode(intval){returnfindHelper(root,val);}// 删除voidremove(intval){root=removeHelper(root,val);}// 修改某个节点的值(先查找再修改)boolupdate(intoldVal,intnewVal){Node*node=findNode(oldVal);if(node==nullptr){returnfalse;}// 先删除旧值,再插入新值(最安全,避免破坏 BST 性质)remove(oldVal);insert(newVal);returntrue;}// 中序遍历(应该输出有序序列)voidinorder(){cout<<"中序遍历: ";inorderHelper(root);cout<<endl;}// 层序遍历(调试用)voidlevelOrder(){if(!root)return;queue<Node*>q;q.push(root);cout<<"层序遍历: ";while(!q.empty()){Node*node=q.front();q.pop();cout<<node->val<<" ";if(node->left)q.push(node->left);if(node->right)q.push(node->right);}cout<<endl;}// 判断是否为空boolempty()const{returnroot==nullptr;}// 获取根节点值(仅用于调试)intgetRootVal()const{returnroot?root->val:-1;}};// 测试代码intmain(){BinarySearchTree bst;// 插入测试vector<int>arr={50,30,70,20,40,60,80,15,25,35,45};for(intx:arr){bst.insert(x);}cout<<"插入后:"<<endl;bst.inorder();// 应该有序bst.levelOrder();// 查找cout<<"\n查找 40: "<<(bst.find(40)?"存在":"不存在")<<endl;cout<<"查找 100: "<<(bst.find(100)?"存在":"不存在")<<endl;// 修改(把 40 改为 42)cout<<"\n修改 40 → 42: "<<(bst.update(40,42)?"成功":"失败")<<endl;bst.inorder();// 删除cout<<"\n删除 30:"<<endl;bst.remove(30);bst.inorder();cout<<"\n删除 70(有两个孩子):"<<endl;bst.remove(70);bst.inorder();cout<<"\n删除 15(叶子节点):"<<endl;bst.remove(15);bst.inorder();return0;}

快速记忆要点(面试/刷题常用)

操作 | 时间复杂度(平均) | 时间复杂度(最坏) | 备注
—|—|—
查找 | O(log n) | O(n) | 最坏退化为链表
插入 | O(log n) | O(n) | 同上
删除 | O(log n) | O(n) | 两个孩子的情况最复杂
中序遍历 | O(n) | O(n) | 天然有序

常见面试追问方向

  1. 如何判断一棵二叉树是否是 BST?(中序遍历是否严格递增)
  2. 如何求 BST 的第 k 小元素?(中序遍历计数 / 记录子树大小)
  3. BST 如何转成双向链表?(中序遍历 + 指针调整)
  4. 如何在 BST 中找最近公共祖先?(类似二叉树 LCA,但利用大小关系更快)
  5. 如何实现一个支持重复元素的 BST?(在 Node 中加 count 字段)

需要哪一部分再展开讲解(比如删除两种写法对比、平衡 BST 引出 AVL/红黑树、BST 转链表代码等),可以直接告诉我~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 13:33:46

Z-Image-Turbo避坑指南:这些启动细节千万别忽略

Z-Image-Turbo避坑指南&#xff1a;这些启动细节千万别忽略 你兴冲冲下载了Z-Image-Turbo镜像&#xff0c;docker run一气呵成&#xff0c;supervisorctl start z-image-turbo敲得行云流水&#xff0c;浏览器打开127.0.0.1:7860——结果页面空白、加载转圈、控制台报错404&…

作者头像 李华
网站建设 2026/4/23 13:33:05

DFS-字符串分割-数字字符串转化成IP地址

求解代码 ArrayList<String> ans new ArrayList<>();public ArrayList<String> restoreIpAddresses (String s) {if(snull||s.length()<4||s.length()>12){return ans;}StringBuilder sb new StringBuilder();dfs(s,sb,0,0);return ans;}private vo…

作者头像 李华
网站建设 2026/4/23 13:31:30

技术演进中的开发沉思-328 JVM:垃圾回收(上)

在 JVM 的内存管理中&#xff0c;“判定对象是否存活” 是 GC 的核心前提 —— 如果把 GC 比作 JVM 的 “垃圾清洁工”&#xff0c;那可达性分析算法就是 “清洁工的判定标准”&#xff0c;引用类型就是 “给对象贴的不同标签”&#xff1a;有的对象&#xff08;强引用&#xf…

作者头像 李华
网站建设 2026/4/23 13:31:43

YOLOv5主干网络替换实战:基于ShuffleNetV2的轻量化改进与性能优化教程

文末含资料链接和视频讲解! 文章目录 一、轻量化网络技术背景 1.1 移动端部署的挑战 1.2 ShuffleNet系列演进 二、ShuffleNetV2模块深度解析 2.1 通道混洗机制 2.2 Shuffle_Block结构 三、YOLOv5集成ShuffleNetV2全流程 3.1 代码修改实战 步骤1:common.py新增模块 步骤2:yo…

作者头像 李华
网站建设 2026/4/23 11:23:07

TurboDiffusion使用贴士:提高生成成功率的种子筛选法

TurboDiffusion使用贴士&#xff1a;提高生成成功率的种子筛选法 1. TurboDiffusion是什么 TurboDiffusion是由清华大学、生数科技与加州大学伯克利分校联合推出的视频生成加速框架&#xff0c;专为文生视频&#xff08;T2V&#xff09;和图生视频&#xff08;I2V&#xff09…

作者头像 李华