[英]c++ Binary Search tree Deletion
所以,我的問題是我不明白為什么這行不通。 我在下面的評論中說,父母顯然沒有初始化過。 我是在做錯誤的指針嗎,我是在使邏輯倒退嗎?我還是相距太遠,最好還是從頭開始? 這是我遇到的最困難的任務,因此任何幫助都是非常有益的。
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;
}
}
}
1.我首先看到的是:
while(curr != NULL)
{
//stuff
}
如所寫,似乎在循環結束時curr == NULL
懶惰的我不得不查看循環的內容以注意到中斷。 如果循環中有較大的塊,則中斷可能更不明顯。 這不是一個好習慣。
使用布爾值(例如bool isNodeFound;),它便宜(一點點),而且更加清晰。 while(curr!= NULL &&!isNodeFound)乍一看更清楚您的意圖,而無需查看循環的內容。
2.如果確實沒有在循環中中斷並且curr == NULL怎么辦? 您的下一條指令curr-> 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
}
嘗試以相同的心態,更清晰和測試的方式分析代碼的其余部分,讓我知道它是否有效。
大家。 有一天,當我需要功能來刪除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;
}
}
}
}
希望此代碼可以在需要時幫助其他人!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.