【发布时间】:2021-02-21 09:32:45
【问题描述】:
我在从 BST 中删除节点时遇到问题。我写了一个搜索节点的方法,效果很好,当我试图删除一个叶子时(到目前为止我写的唯一情况)它会导致错误 (0xDDDD...)在印刷方法上。我认为这是因为打印方法遇到某种空值,但我不知道如何解决这个问题。这是代码... 按值方法删除节点:
void deleteNodeByValue(T val)
{
cout << "\nElement to delete: " << val << " \n";
Node<T>* tmp = root;
while (tmp != NULL)
{
if (val == tmp->data)
{
cout << "Element found: " << tmp->data << " \n";
if (tmp->right_child == NULL && tmp->left_child == NULL)
{
delete tmp;
tmp = NULL;
size--;
}
break;
}
else if (val > tmp->data)
{
tmp = tmp->right_child;
}
else if (val < root->data)
{
tmp = tmp->left_child;
}
}
}
和树打印:
string to_string()
{
stringstream ss;
Node<T>* tmp = root;
queue<Node<T>*> q;
while (!q.empty() || tmp != NULL)
{
if (tmp != NULL)
{
q.push(tmp);
tmp = tmp->left_child; //debugger shows error in this place
}
else
{
tmp = q.front();
q.pop();
ss << "Data: " << tmp->data;
if (tmp->left_child != NULL)
{
ss << " Left child: " << tmp->left_child->data;
}
if (tmp->right_child != NULL)
{
ss << " Right child: " << tmp->right_child->data;
}
ss << " \n";
tmp = tmp->right_child;
}
}
return ss.str();
它还会导致其他方法出现错误,例如获取树高或按顺序获取树等。 我该怎么办?
【问题讨论】:
-
你应该做的是重新开始。这个损坏的代码无法以任何合理的方式修复。至少有两个基本缺陷:节点被删除,但来自其父节点的指针保持不变,因此迭代 BST 最终将取消引用垃圾指针making demons fly out of your nose。只有当它是叶节点时它才会被删除,而当它不是叶节点时不会发生任何事情。这显然也是错误的。树需要重新平衡,这是很多代码,无处可寻。这是无法修复的。从头开始。
-
@SamVarshavchik 我的印象是 BST(与 RB 树或类似树相反)不能保证是平衡的,因此不需要在删除后重新平衡。
-
好吧,@MikeVine,为了删除非叶节点,需要重新平衡某些东西,或者需要做一些事情。但是显示的代码绝对没有任何作用。
-
我想我认为重新平衡是在删除或插入之后完成的事情 - 保证树保持平衡。删除不需要这样做 - 尽管我同意它确实需要做更多的工作并且写错了
标签: c++ search tree binary nodes