我正在嘗試使用 C 并決定嘗試為二叉樹創建整棵樹洗掉方法。出于某種原因,我不斷收到指標錯誤,因為指標是 0xDDDDDDDD。
如果有人能解釋我為什么它不起作用,我將不勝感激,這樣我就可以了解更多關于指標的資訊。
struct Node {
Node* parent;
Node *left,
*right;
int value;
inline Node() : parent(nullptr), left(nullptr), right(nullptr), value(0){}
~Node() = default;
};
class BST {
public:
Node* root;
public:
BST() = default;
inline BST(int i)
{
root = new Node();
root->value = i;
root->parent = nullptr;
root->left = nullptr;
root->right = nullptr;
}
BST(const BST& bst) = default;
void Insert(int i);
void DeleteAll(Node* node);
};
#include <iostream>
int main()
{
BST t(20);
t.root->left = new Node();
t.root->left->value = 22;
t.root->left->parent = t.root;
t.root->right = new Node();
t.root->right->value = 15;
t.root->right->parent = t.root;
t.DeleteAll(t.root);
}
void BST::Insert(int i)
{
}
void BST::DeleteAll(Node* node)
{
Node* target = node;
std::cout << "Probing node with value " << node->value << std::endl;
if (node->left == nullptr && node->right == nullptr)
{
target = node->parent;
std::cout << "Node deleted with value: " << node->value << std::endl;
delete node;
if (target == nullptr)
{
std::cout << "Found and deleted root!" << std::endl;
return;
}
std::cout << "Parents node value: " << target->value << std::endl;
}
else if (node->left != nullptr)
{
std::cout << "Found left ptr with value: " << node->left->value << std::endl;
target = node->left;
}
else if(node->right != nullptr)
{
std::cout << "Found right ptr with value: " << node->right->value << std::endl;
target = node->right;
}
DeleteAll(target);
}
我得到的控制臺提示是:
Probing node with value 20
Found left ptr with value: 22
Probing node with value 22
Node deleted with value: 22
Parents node value: 20
Probing node with value 20
Found left ptr with value: -572662307
Probing node with value -572662307
在DeleteAll()函式中,當它回傳父節點以搜索是否有任何不為空的子節點時,它總是會找到我之前洗掉的左子節點。不應該為空嗎?
在那里它崩潰了。我不知道為什么要這樣做,但洗掉功能中可能有一些東西。這不是任何型別的作業,我只是想了解為什么這不起作用。
uj5u.com熱心網友回復:
當我運行你的代碼時,我得到這個輸出,它拋出"read access violation":
Found left ptr with value: -572662307
-572662307是一樣的0xDDDDDDDD這是特定于Visual Studio在除錯模式。有時您可能無法獲得此值。
問題是你從來沒有分配記憶體parent(你甚至不需要,稍后會詳細介紹)然后你delete一遍又一遍地嘗試它。
您應該像這樣重寫代碼以更好地理解它:
void DeleteAll(Node* node)
{
printf("node: %p\n", node);
Node* target = node;
if (!node->left && !node->right)
{
target = node->parent; //this was never allocated, supposed to be NULL
delete node;
if (target == nullptr) //target is now undefined, not NULL, can't be tested
return; //we may not get here
}
else if (node->left != nullptr)
target = node->left;
else if (node->right != nullptr)
target = node->right;
DeleteAll(target); //could be deleting the same thing again
}
輸出是這樣的,有不同的數字:
node: 012C5078
node: 012D2F00
node: 012C5078
node: 012D2F00
node: DDDDDDDD
您看到重復的相同值,它試圖洗掉兩次。正確的DeleteAll函式是這樣的:
void BST::DeleteAll(Node* node)
{
if (!node)
return;
DeleteAll(node->left);
DeleteAll(node->right);
delete node;
}
您還需要一個Delete(Node* node, int value)基于 洗掉的不同函式,value,left,right一旦您正確插入專案,并且您想在BST銷毀之前洗掉一些值,就會使用該函式。
試試這個例子:
https://gist.github.com/harish-r/a7df7ce576dda35c9660
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/360390.html
