我是一个初学者,我被困在一个为给定密钥搜索无序二叉树的函数上。节点由值和指向左右节点的指针组成。 这是我的代码:
node *btree::search(int key, node *leaf){
if(leaf != NULL)
{
if(key == leaf->value)
{
return leaf;
}
search(key, leaf->left);
search(key, leaf->right);
}
else
{
return NULL;
}
}
node *btree::search(int key){
return search(key, root);
}
在某些情况下,我的函数返回正确的节点,但在其他情况下,这是运行时错误。这有什么问题,可以怎么做才能解决?而且我不允许使用任何外部库,例如queue或其他。
答案 0 :(得分:1)
这是一个很常见的初学者错误。您的递归函数返回一个节点指针,但是当您进行递归调用时,您将忽略返回值。
search(key, leaf->left);
search(key, leaf->right);
应该看起来像这样
node* ptr = search(key, leaf->left);
if (ptr != NULL)
return ptr;
else
return search(key, leaf->right);
即返回通过在左侧子树中搜索找到的节点,但是如果为NULL,则搜索右侧子树并返回在那里找到的节点(如果有)。
编写递归代码时,不仅要考虑递归调用,还要考虑递归调用返回的结果。
答案 1 :(得分:0)
您调用未定义的行为,因为并非递归函数的所有代码路径都返回值。这可能会导致“运行时错误”,崩溃或仅仅是一些不可预测的结果。
顺便说一句,搜索树的优点通常是,您可以获得具有运行时复杂度n * log(n)的元素的平均访问时间。但是为此必须对树进行排序,而且我无法想象无序二叉树的有效用例。在这种情况下,链表也可以胜任。
如果是有序树:
node *btree::search(int key, node *leaf){
if(leaf != NULL)
{
if(key == leaf->value) {
return leaf;
} else if (key < leaf->value) {
return search(key, leaf->left);
} else {
return search(key, leaf->right);
}
}
else
{
return NULL;
}
}
如果树无序:
node *btree::search(int key, node *leaf){
if(leaf != NULL)
{
if(key == leaf->value) {
return leaf;
}
leaf = search(key, leaf->left);
if (! leaf) {
leaf = search(key, leaf->right);
}
return leaf;
}
else
{
return NULL;
}
}