C++如何实现简单的二叉搜索树BST_C++树形结构插入与查找【手撕】

7次阅读

bst插入查找核心是递归比较左右子树,空位插入、等值返回;新手易错在指针传参(须用引用或二级指针)、内存泄漏(new/delete不匹配)和边界判空(!root不可省)。

C++如何实现简单的二叉搜索树BST_C++树形结构插入与查找【手撕】

直接说结论:BST 的插入和查找核心就两条——递归走左子树(值小)或右子树(值大),空节点处插入,相等即查到;但新手常卡在指针传参、内存泄漏和边界判空上。

插入操作必须用二级指针或引用传参

如果只传 TreeNode*,函数内对指针的修改(比如 root = new TreeNode(val))不会反映到调用方。c++ 没有“指针的指针”自动解引用,必须显式处理。

推荐写法是传 TreeNode*&(引用):

void insert(TreeNode*& root, int val) {     if (!root) {         root = new TreeNode(val);  // ✅ 修改生效         return;     }     if (val < root->val) insert(root->left, val);     else if (val > root->val) insert(root->right, val);     // val == root->val 不插入(去重) }
  • 别用 void insert(TreeNode* root, ...) + 返回新指针,容易漏接返回值
  • 如果坚持用一级指针,必须传 TreeNode**,然后写 *root = new TreeNode(...)
  • 每次 new 后没配对 delete 是常见内存泄漏源头

查找函数返回指针而非 bool 更实用

单纯判断“是否存在”用 bool 足够,但实际中往往需要拿到那个节点(比如后续删它、改值、访问父节点)。所以返回 TreeNode* 更通用:

立即学习C++免费学习笔记(深入)”;

TreeNode* search(TreeNode* root, int val) {     if (!root || root->val == val) return root;     if (val < root->val) return search(root->left, val);     return search(root->right, val); }
  • 返回 nullptr 表示未找到,比 bool 多一层安全校验
  • 注意不能省略 !root 判空,否则 root->val 会崩溃
  • 非递归写法虽省空间,但代码变长且易错(尤其 while 循环里忘记更新当前节点)

构造函数和析构要配套管理内存

手撕 BST 时,TreeNode 类通常只是数据载体,但整棵树的生命周期得有人管。不写析构函数delete root 只删根,子树全 leaked。

简单可靠的递归析构:

void destroy(TreeNode* root) {     if (!root) return;     destroy(root->left);     destroy(root->right);     delete root; }
  • 顺序必须是:先递归销毁左右子树,再 delete 当前节点
  • 如果 BST 封装成类(如 class BST),应在析构函数里调用 destroy(root),并把 root 置为 nullptr
  • 现代 C++ 更推荐用 std::unique_ptr<treenode></treenode>,自动管理,但手撕练习时不建议绕开裸指针直面问题

真正难的不是写对逻辑,而是每次插入后手动画图验证指针连得对不对;一两个节点看不出问题,插十个数后找不着某个节点,八成是某次 root = ... 写成了局部赋值。

text=ZqhQzanResources