我正在编写一个迭代函数来搜索二叉树中的某个值。这是本地化为签名的整数,直到我开始如何泛化类。
假设我的类是BinarySearchTree,它有一个指向树的根节点的指针。还假设通过insert函数插入节点,并指向两个子节点。这是Node结构的缩写版本:
struct Node
{
public:
Node *left_, *right_;
int value_
Node(int val) : value_(val), left_(0), right_(0) { }
//done in this manner to always make sure blank children are
//init to zero, or null
Node(int val, Node *left, Node *right) : value_(val), left_(0), right_(0)
{ left_ = left; right_ = right; }
}
因此,您可以放心地假设节点的uninit指针将为NULL。
这是我的代码:
int BinarySearchTree::search(int val)
{
Node* next = this->root();
while (next->left() != 0 || next->right () != 0)
{
if (val == next->value())
{
return next->value();
}
else if (val < next->value())
{
next = next->left();
}
else if (val > next->value())
{
next = next->right();
}
}
//not found
return 0;
}
此代码被朋友拒绝有两个原因:
1)如果next没有子节点,则两者都将评估为零,我将过早地退出循环(我永远不会检查搜索到的val与下一个值)。
2)如果next有一个子节点,但是你要搜索的数据应该在树的空面,next将被设置为0,它将再次循环,将next(0为0)与像while(0->left())
这样的左右树,导致未定义的行为。
我被告知这两个问题的解决方案都在于循环条件,但我无法看到我能做些什么来轻松地解决这个问题。 Stack Overflow社区能否提供任何见解?
答案 0 :(得分:2)
我认为你应该测试你的循环中next是不是NULL,如下所示:
int BinarySearchTree::search(int val)
{
Node* next = this->root();
while (next)
{
if (val == next->value())
{
return next->value();
}
else if (val < next->value())
{
next = next->left();
}
else if (val > next->value())
{
next = next->right();
}
}
//not found
return 0;
}
答案 1 :(得分:1)
试试这个:
while (next != NULL)
?
答案 2 :(得分:0)
首先,我不确定你为什么要返回int。如果您在树中搜索0,该怎么办?你可能想要这样的东西:
bool BinarySearchTree::Search(int val) {
Node* current = root();
while (current != NULL) {
// Check if it's here
if (val == current->value()) {
return true;
}
if (val < current->value()) {
current = current->left();
} else {
current = current->right();
}
}
// Not found
return false;
}
请注意,循环不变:在每个循环开始时,您处于需要“处理”的非空节点。首先检查它是否是您想要的节点。如果没有,建立一个分支,让循环决定分支是否“好”(即 - 非空)。然后你将让下一个循环迭代处理测试。