插入节点必须用指针引用(Node&)才能修改父节点的left/right字段;find()根据需求返回Node或bool;重复值需显式处理;递归易栈溢出,应考虑迭代实现并注意内存释放。
Node*&)?直接传 Node* 会导致修改形参无法影响实参,新节点只能挂在局部变量上,原树结构不变。用 Node*& 才能真正把新分配的节点地址写回父节点的 left 或 right 字段。
void insert(Node* root, int val) → 插入后 root 仍是空或旧地址void insert(Node*& root, int val) → 可以让 root = new Node(val) 生效insert(root->left, val) 中 root->left 是左指针的引用,才能更新它find() 返回 Node* 还是 bool?取决于使用场景。如果只需要判断存在性,返回 bool 更轻量;如果后续要修改或访问该节点数据,必须返回 Node*(或 const Node*)。
nullptr,不是 NULL(C++11 起推荐用 nullptr)find() 内部做 cout 或抛异常——职责单一,查就是查,输出/错误处理交给调用方begin()/end(),但基础 BST 通常不强制要求标准 BST 定义中,左子树 root,右子树 > root,等于时通常忽略、报错或插入到右子树(视需求而定)。C++ 实现必须显式决定行为,不能默认“随便放”。
if (val == root->val) return;
else if (val >= root->val) insert(root->right, val);
struct Node { int val; int count; Node *left, *right; };,遇到相等只 ++count
struct Node {
int val;
Node* left;
Node* right;
Node(int v) : val(v), left(nullptr), right(nullptr) {}
};
void insert(Node*& root, int val) {
if (!ro
ot) {
root = new Node(val);
return;
}
if (val < root->val)
insert(root->left, val);
else if (val > root->val)
insert(root->right, val);
// 默认忽略重复;如需处理重复,此处加 else 分支
}
Node find(Node root, int val) {
if (!root || root->val == val)
return root;
return val < root->val ? find(root->left, val) : find(root->right, val);
}
递归实现简洁,但深度大时可能栈溢出;生产环境若树高不可控,应改用迭代版 insert 和 find。另外,所有动态分配的 Node* 必须配对 delete,否则内存泄漏——这点容易被初学者完全忽略。