You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BST节点删除异常:指针未正确置空问题排查

问题分析与修复方案

你的问题核心不是内存泄漏,而是悬空指针+父节点指针未正确更新的问题,我来帮你拆解清楚:

问题根源

你在trimBST函数里传递的是指针的值拷贝,而非指针的引用,导致子树的修改无法同步到上层父节点:

  • trimBST的参数是tree_node<T> *root(值传递),当你调用trimBST(node->left, L, R)时,传递的是node->left的副本,不是指向node->left本身的引用。
  • 虽然search_and_delete用了tree_node<T> *&node(引用传递),能修改当前函数内的node指针,但这个修改只作用于trimBST里的局部root变量,不会影响上层父节点的left/right指针。

所以当你删除节点0并把node置为nullptr时,根节点1的left指针仍然指向原来的内存地址(这块内存已经被释放,变成悬空指针),这就是递归返回后打印node->left还是旧地址的原因。

修复方案

我们可以重构trimBST的逻辑,让它返回修剪后的子树指针,然后父节点用返回值更新自己的left/right指针,这是二叉树递归处理的常规思路:

template <typename T>
class Solution {
public:
    tree_node<T> *trimBST(tree_node<T> *root, int L, int R) {
        if (!root) {
            return nullptr;
        }

        // 先递归修剪左右子树,更新当前节点的左右指针
        root->left = trimBST(root->left, L, R);
        root->right = trimBST(root->right, L, R);

        // 处理当前节点是否需要删除
        if (root->val < L) {
            // 当前节点值小于L,删除它,返回修剪后的右子树
            tree_node<T>* temp = root->right;
            delete root;
            return temp;
        } else if (root->val > R) {
            // 当前节点值大于R,删除它,返回修剪后的左子树
            tree_node<T>* temp = root->left;
            delete root;
            return temp;
        }

        // 当前节点符合范围,直接返回
        return root;
    }
};

为什么这个方案能解决问题?

  • 递归修剪左子树后,root->left会被更新为修剪后的结果(如果左节点被删除,就会变成nullptr或者它的合法子树)。
  • 当处理节点0时,它的val < 1,会被删除并返回nullptr,根节点的left就会被设置为nullptr,彻底解决悬空指针问题。
  • 这个逻辑也正确处理了所有节点情况(包括有两个子节点的场景),避免了原代码中可能出现的树结构破坏或内存泄漏。

原代码的其他潜在问题

你原来的search_and_delete函数还有一些逻辑漏洞:

  • 直接删除节点的子节点(比如delete node->right)不符合BST的删除规范,会破坏树结构。
  • 没有处理节点有两个子节点的情况,实际场景中会导致错误。
    上面的重构方案已经覆盖了这些情况。

内容的提问来源于stack exchange,提问作者24n8

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:28:38