[英]C++ Binary Search Tree and Pointers
你能告诉我为什么调用binaryTree.Exists(5);
方法binaryTree.Exists(5);
说“二叉树中不存在 5”? 调试时,就像尝试访问已插入 5 的节点不再存在一样。 我不明白为什么。 谢谢你!!!
#include <iostream>
using namespace std;
class Node
{
private:
int _value;
Node* left;
Node* right;
public:
Node(int value):_value(value), left(NULL), right(NULL)
{
}
Node* returnLeftChild()
{
return left;
}
Node* returnRightChild()
{
return right;
}
void setLeftChild(Node* l)
{
left=l;
}
void setRightChild(Node* r)
{
right=r;
}
int getValue()
{
return _value;
}
};
class BinaryTree
{
private:
Node parent;
void AddToOneTree(Node* parent, int value)
{
if (value==parent->getValue())
{
return;
}
if (value>parent->getValue())
{
if (parent->returnRightChild()==NULL)
{
Node newNode(value);
parent->setRightChild(&newNode);
return;
}
else
{
AddToOneTree(parent->returnRightChild(), value);
}
}
if (value<parent->getValue())
{
if (parent->returnLeftChild()==NULL)
{
Node newNode(value);
parent->setLeftChild(&newNode);
return;
}
else
{
AddToOneTree(parent->returnLeftChild(), value);
}
}
}
void LookForValue(Node* parent, int value, bool found)
{
if (value>parent->getValue())
{
if (parent->returnRightChild()!=NULL)
{
if (parent->returnRightChild()->getValue()==value)
{
found= true;
goto HERE;
}
else
{
LookForValue(parent->returnRightChild(), value, found);
}
}
}
else if (value<parent->getValue())
{
if (parent->returnLeftChild()!=NULL)
{
if (parent->returnLeftChild()->getValue()==value)
{
found= true;
goto HERE;
}
else
{
LookForValue(parent->returnLeftChild(), value, found);
}
}
}
HERE:;
}
public:
BinaryTree(int parentValue):parent(parentValue)
{
}
void Add(int value)
{
AddToOneTree(&parent, value);
}
void Exists(int value)
{
bool found = false;
if (parent.getValue()==value)
{
cout << value << " exists in the Binary Tree." << endl;
}
else{
LookForValue(&parent, value, found);
if (found)
{
cout << value << " exists in the Binary Tree." << endl;
}else
{
cout << value << " doesn't exist in the Binary Tree." << endl;
}
}
}
};
int main()
{
BinaryTree binaryTree(9);
binaryTree.Add(5);
binaryTree.Add(5);
binaryTree.Exists(9);
binaryTree.Exists(5);
}
至少函数AddToOneTree
是错误的,是程序未定义行为的原因
例如在这个代码块中
if (parent->returnRightChild()==NULL)
{
Node newNode(value);
parent->setRightChild(&newNode);
return;
}
您创建一个局部变量newNode
并将其地址分配给右孩子的指针。 然而,由于变量是局部的,它在控件离开代码块后被销毁,树中相应的指针将无效。
您需要动态分配节点并将它们添加到树中。
更好的设计是,当类BinaryTree
包含ponter树的头部。 像这样声明数据成员父级
class BinaryTree
{
private:
Node *parent;
^^^^^^^^
//...
并相应地重写该类。:)
您应该替换此字符串:
void LookForValue(Node* parent, int value, bool found)
对此:
void LookForValue(Node* parent, int value, bool &found)
或者只是在LookForValue
函数中将返回值设置为bool
并编写如下内容:
found = LookForValue(&parent, value, found);
您的代码中有几个问题。
第一个是LookForValue
函数永远不会返回找到的布尔值。 您可以将 bool found 更改为 bool & found 以便您不必返回任何内容,或者将LookForValue
的返回类型LookForValue
为bool
在这种情况下,您需要将代码更改为如下所示:
bool LookForValue(Node* parent, int value, bool found)
{
if (value>parent->getValue())
{
if (parent->returnRightChild()!=NULL)
{
if (parent->returnRightChild()->getValue()==value)
{
return true ;
}
else
{
LookForValue(parent->returnRightChild(), value, found);
}
}
}
else if (value<parent->getValue())
{
if (parent->returnLeftChild()!=NULL)
{
if (parent->returnLeftChild()->getValue()==value)
{
return true ;
}
else
{
LookForValue(parent->returnLeftChild(), value, found);
}
}
}
}
如果您更改返回类型,请考虑在您的Exists
函数中更改else
之后的一行:
found = LookForValue(&parent, value, found);
我还没有测试代码,所以可能还有其他问题。
下次遇到这样的问题时,我建议尝试使用 gdb,因为它可能有助于检测您的代码真正在做什么,以便您可以找出可能出错的地方。 例如,在这里,您可以看到,仅通过逐步“打印”您的found
变量的值,您的Exists
函数中的 found 从未设置为 true 。
另外,我认为您设计课程的方式并不是很好。 Parent 应该是一个指针,指向树的根。 我建议您完全重新设计您的代码。 你可以在网上找到一些很好的实现,你可以将它们作为你的代码。
最后 goto 绝对是一个坏主意......我也会摆脱它。
void LookForValue(Node* parent, int value, bool found)
您正在通过值found
。 这意味着该值将被复制。 当您在LookForValue
方法内部更改found
,您只是在更改此副本。
void LookForValue(Node* parent, int value, bool& found)
这将通过引用传递 found,因此如果您在LookForValue
更改它, Exists
方法中的原始值也将更改。
你也可以像这样返回一个 bool 值:
bool LookForValue(Node* parent, int value, bool &found)
然后只写return true;
代替
found= true;
goto HERE;
这样你也可以摆脱 goto。
谢谢大家。 我已经更改了通过引用找到的传递并使用“new”为新点头分配了内存。现在可以使用了!!
#include <iostream>
using namespace std;
class Node
{
private:
int _value;
Node* left;
Node* right;
public:
Node(int value):_value(value), left(NULL), right(NULL)
{
}
Node* returnLeftChild()
{
return left;
}
Node* returnRightChild()
{
return right;
}
void setLeftChild(Node* l)
{
left=l;
}
void setRightChild(Node* r)
{
right=r;
}
int getValue()
{
return _value;
}
};
class BinaryTree
{
private:
Node parent;
void AddToOneTree(Node* parent, int value)
{
if (value==parent->getValue())
{
return;
}
if (value>parent->getValue())
{
if (parent->returnRightChild()==NULL)
{
Node* newNode=new Node(value);
parent->setRightChild(newNode);
return;
}
else
{
AddToOneTree(parent->returnRightChild(), value);
}
}
if (value<parent->getValue())
{
if (parent->returnLeftChild()==NULL)
{
Node* newNode=new Node(value);
parent->setLeftChild(newNode);
return;
}
else
{
AddToOneTree(parent->returnLeftChild(), value);
}
}
}
void LookForValue(Node* parent, int value, bool &found)
{
if (value>parent->getValue())
{
if (parent->returnRightChild()!=NULL)
{
if (parent->returnRightChild()->getValue()==value)
{
found= true;
goto HERE;
}
else
{
LookForValue(parent->returnRightChild(), value, found);
}
}
}
else if (value<parent->getValue())
{
if (parent->returnLeftChild()!=NULL)
{
if (parent->returnLeftChild()->getValue()==value)
{
found= true;
goto HERE;
}
else
{
LookForValue(parent->returnLeftChild(), value, found);
}
}
}
HERE:;
}
public:
BinaryTree(int parentValue):parent(parentValue)
{
}
void Add(int value)
{
AddToOneTree(&parent, value);
}
void Exists(int value)
{
bool found = false;
if (parent.getValue()==value)
{
cout << value << " exists in the Binary Tree." << endl;
}
else{
LookForValue(&parent, value, found);
if (found)
{
cout << value << " exists in the Binary Tree." << endl;
}else
{
cout << value << " doesn't exist in the Binary Tree." << endl;
}
}
}
};
int main()
{
BinaryTree binaryTree(9);
binaryTree.Add(5);
binaryTree.Add(6);
binaryTree.Add(1);
binaryTree.Add(15);
binaryTree.Add(13);
binaryTree.Add(2);
binaryTree.Add(2);
binaryTree.Add(0);
binaryTree.Add(4);
binaryTree.Exists(9);
binaryTree.Exists(5);
binaryTree.Exists(6);
binaryTree.Exists(1);
binaryTree.Exists(15);
binaryTree.Exists(13);
binaryTree.Exists(2);
binaryTree.Exists(2);
binaryTree.Exists(0);
binaryTree.Exists(4);
binaryTree.Exists(11);
binaryTree.Exists(412);
binaryTree.Exists(40);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.