在二叉搜索树功能中使用指向指针的指针时出错
Error when working with pointer to a pointer in Binary Search Tree functionality
我有以下代码:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
using namespace std;
struct Node
{
int value;
Node *left, *right;
Node(int value, Node *l = NULL, Node *r = NULL)
{
this->value = value;
left = l;
right = r;
}
};
struct BST
{
Node *root = NULL;
void insert(int value)
{
cout<<"Inserting: "<<value<<endl;
Node **current = &root;
while(*current != NULL)
{
if(value >= (*current)->value)
{
current = &((*current)->right);
}
else current = &((*current)->left);
}
(*current) = new Node(value);
}
void remove(int value)
{
Node *toRemove = search(value);
remove(toRemove);
}
void remove(Node *toReplace)
{
if(toReplace == NULL) return;
Node *toBeReplacedWith = NULL;
if(toReplace->left == NULL && toReplace->right == NULL)
{
delete toReplace;
toReplace = NULL;
return;
}
if((toReplace->left == NULL) ^ (toReplace->right == NULL))
{
if(toReplace->left != NULL) toBeReplacedWith = toReplace->left;
else toBeReplacedWith = toReplace->right;
copyAndDeleteNode(toReplace, toBeReplacedWith);
return;
}
Node *current = toReplace->left;
while(current->right != NULL) current = current->right;
toReplace->value = current->value;
remove(current);
}
Node* search(int value)
{
Node *current = root;
while(current != NULL && current->value != value)
{
if(current->value > value) current = current->left;
else current = current->right;
}
if(current == NULL)
{
cout<<"The node didn't exist in the BST";
}
return current;
}
void traverse()
{
rec_traverse(root);
}
private:
void copyAndDeleteNode(Node *toReplace, Node *toBeReplacedWith)
{
toReplace->value = toBeReplacedWith->value;
toReplace->left = toBeReplacedWith->left;
toReplace->right = toBeReplacedWith->right;
delete toBeReplacedWith;
toBeReplacedWith = NULL;
}
void rec_traverse(Node * current)
{
if(current == NULL) return;
rec_traverse(current->left);
cout<<current->value<<endl;
rec_traverse(current->right);
}
};
int main()
{
BST tree;
for(int i = 0; i < 10; ++i)
{
tree.insert(i);
}
Node *a = tree.search(6);
cout<<"found val: "<<a->value<<endl;
tree.remove(5);
tree.remove(9);
tree.remove(2);
// tree.insert(4);
//tree.insert(15);
tree.insert(6);
tree.insert(22222);
cout<<"Traversing:n";
tree.traverse();
return 0;
}
由于某些原因,在执行时,程序在insert(22222)
上崩溃,而之前的调用没有问题,我不明白为什么。问题必须在第26-30行之间,我总是在节点构造函数中放置NULL值,所以我很困惑为什么循环不会中断。
有一件事是错误的:
remove(Node* toReplace)
。
该函数不更新您的Node指针,因为您是按值传递指针。只要remove
返回,该函数中以任何方式改变toReplace
指针的所有代码都将被丢弃。
例如:
delete toReplace;
toReplace = NULL;
delete
完成了,但是将指针设置为NULL没有任何作用,因为toReplace
是一个局部变量。
你需要把你的原型改成这样:
remove(Node *& toReplace)
。
向指针传递引用现在允许更新指针值并将其反射回调用者。
同样,在删除'9'的叶节点后,您没有检查树的状态。如果你这样做了,你应该清楚地看到你的新叶节点'8'有一个坏的"右"指针。当您尝试添加一个大于8的节点(22222)时,这会导致各种各样的问题。
您的remove
功能在这里出现故障:
if(toReplace->left == NULL && toReplace->right == NULL)
{
delete toReplace;
toReplace = NULL;
return;
}
好,所以您删除了节点(假设它是'9'节点)。那么原来指向'9'的节点呢?您没有将它的右(或左)指针调整为现在指向NULL。这就是问题的根源。
所有这些都可以被检测到,如果您只是查看您的树,看看它是否在每次操作后仍然是正确的。您可以直接使用调试器,或者甚至只是在每个阶段打印出树的状态。
最后,树结构缺少析构函数。你分配了内存,但是没有任何地方释放它。
编辑:这行应该做什么?更具体地说,^
应该做什么?
if((toReplace->left == NULL) ^ (toReplace->right == NULL))
相关文章:
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- 将链表转换为指针数组时出错
- 尝试将指针与结构一起使用时出错
- 将类指针类型转换为键时出错
- 如果我在指针中使用 ++ 操作数,我的值就会出错
- 在 Clang 中使用指向成员的指针时出错
- 编译包含指向模板函数的指针的初始值设定项列表时,gcc 出错,但 clang 不出错
- 通过在迭代指针键映射上出错来捕获非确定性
- 调用指向成员函数的指针时出错
- 通过具有矢量基址的指针读取矢量元素时出错
- 尝试返回指向 Visual Studio 中的动态数组的指针时出错C++
- 将空间分配给整数指针时出错
- GNU 链接器:如果头文件中的指针被声明为 NULL 和/或 extern,则出错
- 尝试将结构指针传递给类时出错
- 我设计了一个类并创建了基指针,但是当我尝试通过基指针访问派生函数时,它会出错
- 非标准语法;使用 '&' 创建指向成员的指针错误,将成员函数分配给向量时出错
- 指向 2D 数组的指针出错
- 删除vector中的指针出错
- 在c++函数中使用指针出错
- 指向数组参数的双指针出错