我正在尝试为二叉搜索树实现递归删除算法,并且已经成功完成了但是它打破了排序算法(依次,预订和后序)。继承我的删除功能代码
void remove_rec(string word, Node* ptr) {
if (word < ptr->data && ptr->left != nullptr) {
remove_rec(word, ptr->left);
}
else if (word > ptr->data && ptr->right != nullptr) {
remove_rec(word, ptr->right);
}
else {
//if the node has no children
if (ptr->left == nullptr && ptr->right == nullptr) {
delete(ptr);
ptr = nullptr;
}
//if there is a right child
else if (ptr->left == nullptr && ptr->right != nullptr) {
Node* temp = ptr;
ptr = ptr->right;
delete temp;
}
//if there is a left child
else if (ptr->left != nullptr && ptr->right == nullptr) {
Node* temp = ptr;
ptr = ptr->left;
delete temp;
}
}
}
当递归调用inorder(或任何其他排序方法)并且左或右节点为空时,程序似乎崩溃。程序不是跳过if语句,而是继续尝试访问左节点,直到它崩溃并出现错误“读取访问冲突”。如果我不调用remove_rec函数,则排序函数按预期工作。对我来说,似乎我在删除节点后没有正确构建树。任何帮助深表感谢!我只包括我认为导致问题的代码,如果没有调用该函数,一切都按预期工作。
答案 0 :(得分:0)
您没有修改您认为自己的指针。行
ptr
修改本地参数Node
,它是您ptr
个孩子之一的独特副本。您需要通过引用传递delete
以使修改生效。
您获得“读取访问权限”的原因是因为节点中指针的值仍然与删除之前相同,但它现在无效,因为您{{ 1}} d对象。
您也在复制您要搜索的数据,效率很低。
void remove_rec(const std::string & word, Node *& ptr) {
if (word < ptr->data && ptr->left != nullptr) {
remove_rec(word, ptr->left);
}
else if (word > ptr->data && ptr->right != nullptr) {
remove_rec(word, ptr->right);
}
else {
//if the node has no children
if (ptr->left == nullptr && ptr->right == nullptr) {
delete(ptr);
ptr = nullptr;
}
//if there is a right child
else if (ptr->left == nullptr && ptr->right != nullptr) {
Node* temp = ptr;
ptr = ptr->right;
delete temp;
}
//if there is a left child
else if (ptr->left != nullptr && ptr->right == nullptr) {
Node* temp = ptr;
ptr = ptr->left;
delete temp;
}
// TODO: handle case when node has both left and right child
}
}
另外,我会将Node
更改为使用std::unique_ptr<Node>
left
和right
。如果您将来犯同样的错误,则会出现编译时错误。