【发布时间】:2009-07-11 03:37:59
【问题描述】:
我正在编写一个迭代函数来搜索二叉树的某个值。在我了解如何泛化类之前,这已本地化为带符号的整数。
假设我的类是 BinarySearchTree,它有一个指向树根节点的指针。还假设节点是通过插入函数插入的,并且具有指向两个子节点的指针。这是 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 与 next 的值)。
2) 如果 next 有一个子节点,但您要搜索的数据应该在树的空边,next 将被设置为 0,它会再次循环,将 next(即 0)与像while(0->left()) 这样的左右树,导致未定义的行为。
有人告诉我,这两个问题的解决方案都在于循环条件,但我看不出我能做些什么来轻松解决这种情况。 Stack Overflow 社区能否提供任何见解?
【问题讨论】:
-
我讨厌添加作业标签。这不是作业,我不在学校,这是一种爱好。
-
@Hooked:我刚刚添加了算法标签。另外,我意识到我刚刚发布了几乎相同的代码,但请阅读我的帖子...考虑返回 bool 而不是 int。
-
@Hooked:无意冒犯。我只是误解了“代码被拒绝”。既然你拒绝的朋友没有给你一个理由,我认为这是因为这是家庭作业——在这种情况下,放弃答案是不好的形式。
-
@Hooked:你明白我为什么建议你将返回值更改为 bool 吗?当你搜索 0 时会发生什么?你怎么知道是否找到了 0,或者什么也没找到?您将编写类似“if (tree.Search(0) == 0)”的代码,但这是错误的。即使 "if (tree.Search(1) == 1)" 可以工作,它也很尴尬。您希望能够编写“if (tree.Search(0))”... 这有意义吗?
-
@tvanfosson:没关系,但是作业有你不愿意做自己的工作的内涵。我这样做只是因为它很有趣。我现在进入了一个论坛帖子的第 22 页(20 个帖子/页),有两个共同的朋友(和程序员)教我如何编程。
标签: algorithm binary-tree treenode tree-search