所以,我的问题是我不明白为什么这不起作用。我在下面评论说它显然从未初始化父级。我的指针是错误的,我是否向后倾斜逻辑我到目前为止,从头开始会更好吗?这是我遇到的最困难的任务,所以任何帮助都会非常有益。
void Dictionary::remove(string word)
{
if(root == NULL)
{
cout << "list is empty\n";
return;
}
DictionaryNode *curr = root;
DictionaryNode *parent = NULL;`
while(curr != NULL)
{
if(curr->word == word)
break;
else
{
parent = curr;
if(word > curr->word)
curr = curr->right;
else
curr = curr->left;
}
}
//LEAF node.
if(curr->left == NULL && curr->right == NULL)
{
if(parent->left == curr) // Right here is an access violation. Which doesn't //make sense.
{
parent->left = NULL;
}
else
{
parent->right = NULL;
}
delete curr;
}
/*
* Node has a single child LEFT or RIGHT
*/
if((curr->left == NULL && curr->right != NULL) || (curr->left != NULL && curr->right == NULL))
{
if(curr->left == NULL && curr->right != NULL)
{
if(parent->left == curr) //if(parent->left == curr) //says parent is //not intialized
{
parent->left = curr->right;
delete curr;
}
else
{
parent->right = curr->right;
delete curr;
}
}
else
{
if(parent->left == curr)
{
parent->left = curr->left;
delete curr;
}
else
{
parent->right = curr->left;
delete curr;
}
}
}
if (curr->left != NULL && curr->right != NULL)
{
DictionaryNode* temp;
if(parent == NULL || parent->left==curr)
{
temp = curr->right;
while(temp->left!=NULL)
temp = temp->left;
if(parent!=NULL)
parent->left = curr->right;
else
root = curr->right;
temp->left = curr->left;
curr->left = curr->right=NULL;
delete curr;
}
else if(parent->right==curr)
{
temp = curr->left;
while(temp->right!=NULL)
temp = temp->right;
parent->right=curr->left;
temp->right = curr->right;
curr->left = curr->right=NULL;
delete curr;
}
}
}
答案 0 :(得分:0)
1。 我首先看到的是:
while(curr != NULL)
{
//stuff
}
正如它所写,似乎在你的循环结束时curr == NULL
懒惰我不得不看一下循环的内容以注意休息。在循环中使用更大的块时,中断可能更不明显。 这不是一个好习惯。
使用bool(例如:bool isNodeFound;),它便宜(一点)并使其更清晰。 虽然(curr!= NULL&amp;&amp;!isNodeFound)乍看之下更清楚你的意图,而不会看你的循环内容。
2.如果确实你没有在循环中点击中断并且curr == NULL? 你的下一条指令curr-&gt; left会失败! 好像布尔会再次有用!
if(!isNodeFound)
{
//log error if you can "cannot remove node because it is not in dictionary"
return false; //make your function a bool to return if it succeeded or not
}
尝试使用相同的心态,更清晰和测试来分析其余代码,让我知道它是否有效。
答案 1 :(得分:0)
每个人。有一天,当我需要功能来删除BST中的树节点时,我搜索了这个问题。因此,这个问题很好,我在上面的代码中进行了编辑和检查,然后代码真正成功运行了。上面的代码错过了一些实例,请按照下面的说明进行操作:
首先,已删除的节点为LEAF NODE。您错过了一个实例,该实例的节点是根节点或叶节点(即BST仅具有一个节点)。因此,parent为NULL,parent-> left / right无效。
第二个已删除节点的左侧或右侧有一个子树。因此,如果删除的节点是根节点,则这与“第一”类似。
第三个已删除的节点具有left和righr子树。您考虑过“父母”,但不应使用“ if(父母== NULL || parent-> left == curr)”,就好像parent = NULL一样,以便parent-> left无效。您应该将“ if(parent == NULL){...} else {if(parent-> left == curr)...}”。
最后,使用if ... else-if ... else而不是使用if ... if ... if,因为您删除了“ curr”,那么您将不会在任何地方知道“ curr”点,而“ if “下一个仍然会检查” curr”错误。
下面的编辑代码可满足任何人的需要,
void Dictionary::remove(string word)
{
if(root == NULL)
{
cout << "list is empty\n";
return;
}
DictionaryNode *curr = root;
DictionaryNode *parent = NULL;
while(curr != NULL)
{
if(curr->word == word)
break;
else
{
parent = curr;
if(word > curr->word)
curr = curr->right;
else
curr = curr->left;
}
}
//LEAF node.
if(curr->left == NULL && curr->right == NULL)
{
if (parent == NULL) {
delete curr;
} else {
if(parent->left == curr) // Right here is an access violation. Which doesn't //make sense.
{
parent->left = NULL;
}
else
{
parent->right = NULL;
}
delete curr;
}
}
/*
* Node has a single child LEFT or RIGHT
*/
else if((curr->left == NULL && curr->right != NULL) || (curr->left != NULL && curr->right == NULL))
{
if(curr->left == NULL && curr->right != NULL)
{
if (parent == NULL) {
root = curr->right;
curr->right = NULL;
delete curr;
} else {
if(parent->left == curr) //if(parent->left == curr) //says parent is //not intialized
{
parent->left = curr->right;
delete curr;
}
else
{
parent->right = curr->right;
delete curr;
}
}
}
else
{
if (parent == NULL) {
root = curr->left;
curr->left = NULL;
delete curr;
} else {
if(parent->left == curr)
{
parent->left = curr->left;
delete curr;
}
else
{
parent->right = curr->left;
delete curr;
}
}
}
}
else
{
DictionaryNode* temp;
if(parent == NULL)
{
temp = curr->right;
while(temp->left!=NULL)
temp = temp->left;
if(parent!=NULL)
parent->left = curr->right;
else
root = curr->right;
temp->left = curr->left;
curr->left = curr->right=NULL;
delete curr;
} else {
if(parent->left==curr){
temp = curr->right;
while(temp->left!=NULL)
temp = temp->left;
if(parent!=NULL)
parent->left = curr->right;
else
root = curr->right;
temp->left = curr->left;
curr->left = curr->right=NULL;
delete curr;
}
else if(parent->right==curr)
{
temp = curr->left;
while(temp->right!=NULL)
temp = temp->right;
parent->right=curr->left;
temp->right = curr->right;
curr->left = curr->right=NULL;
delete curr;
}
}
}
}
希望此代码可以在其他人需要时提供帮助!