我正在解决在二进制树中插入节点的问题。我有以下疑问:
1)如果要插入节点,则应该返回一个指向该节点的指针,因为只有这样我们才能访问该节点,对吗?
2)那么为什么我们要返回root?我们必须相应地返回root->left
或root->right
,我在哪里错了?
struct node* insert(struct node* root, int data)
{
if (root == NULL) //If the tree is empty, return a new,single node
return newNode(data);
else
{
//Otherwise, recur down the tree
if (data <= root->data)
root->left = insert(root->left, data);
else
root->right = insert(root->right, data);
return root;
}
}
3)上面的代码返回的根是否是由于递归而更改过的根?
答案 0 :(得分:1)
您误解了返回值。
此insert
函数的返回值是指向现在已插入data
的子树的指针。如果传入的root
为null,则这是一个新的1节点树。如果传入的root
非null,则返回值是相同的root
。
这使递归更加简单。我们简单地递归,直到我们直接进入分支中的nullptr
。然后递归停止,返回值设置父节点的left
或right
节点。
要创建全新的树,请输入:
node* new_tree = insert(nullptr, 7);
要在现有树中插入内容,请输入:
existing_tree = insert(existing_tree, 7);
或等效地
insert(existing_tree, 7);
只要existing_tree
不为空。
此函数(创建和修改树)的这种“双重使用”可能会造成混淆,但是它使特定的递归使用起来有点冗长,并使“空树是nullptr”和“总是做{ {1}}”是使空树作为空树起作用的规则。
但是,这是一种非常C的处理方式。
另一种c++的处理方式是:
existing_tree = insert(existing_tree, val);
其中数据流入和流出函数的流更为明确,我们假设std::unique_ptr<node> insert(std::unique_ptr<node> root, int data)
{
if (root == nullptr) //If the tree is empty, return a new,single node
return std::make_unique<node>(data);
else
{
//Otherwise, recur down the tree
if (data <= root->data)
root->left = insert(std::move(root->left), data);
else
root->right = insert(std::move(root->right), data);
return std::move(root);
}
}
的构造函数采用node
。
答案 1 :(得分:0)
此递归插入应始终返回树的根节点。仅仅因为您阅读return root
并不意味着原始函数调用已完成执行,仅意味着第n个递归已完成。递归调用已全部压入堆栈,因此必须在原始调用者收到返回值之前全部解决。
您可以通过对插入的值进行find
来返回插入的节点。