二叉树上的递归搜索返回真和假

Recursive search on binary tree returning both true and false

本文关键字:返回 搜索 递归 二叉树      更新时间:2023-10-16

对于赋值,我应该想出一个名为all_less的递归函数,它接受指向任意树(TN<T>*)的指针和一个T参数。如果所有值都小于 T 参数,则返回 true,否则返回 false。

我的Tree类的实例变量是这样的:

T      value;
TN<T>* left;
TN<T>* right;

all_less的函数原型如下所示:

template<class T>
bool all_less(TN<T>* t, T v)

由于我必须考虑一个未排序的二叉树,我认为递归地向下移动每个子树并检查每个值都可以正常工作。测试完这个函数后:

template<class T>
bool all_less(TN<T>* t, T v)
{
    if(v <= t->value) {
        return false;
    } else if(v > t->value) {
        if(t->right != nullptr && t->left != nullptr) {
            all_less(t->right, v);
            all_less(t->left, v);
        }
    }
    return true;
}

在函数几乎总是返回 true 遇到一些问题后,我在 return true 之前放置了一些打印语句,return false看看发生了什么。

例如,假设我们在二叉树中有值 12、15、14、5。使用以下方法运行我的函数:

TN<int>* t;
std::cout << all_less(t, 15); 

作为输入,将输出以下内容:

true
false
true
true
最终

结果最终为 true,即使返回了一次 false。我如何获取它,以便如果它返回 false,函数返回 false 并立即停止?还有没有更好的方法来实现此功能?我最初确实有几个额外的 if-else 语句来检查右/左子树是否为空并从那里继续,但这些似乎实际上并没有做任何事情。

您忽略了递归调用的返回值。

最终

结果最终为 true,即使返回了一次 false。

false是从不同的函数调用返回的,并且已经消失在天空中的大比特桶中。

递归函数的工作方式与任何其他函数完全相同 - 如果您有

int f() { return 0:}
int g(int x) { 
    if (x == 0) 
        f(); 
    return 1; 
}

g(0)将返回 1,即使 0 "返回一次"。
如果g(0)应该返回 f() 的值,它必须显式地执行此操作:

int g(int x) { 
    if (x == 0) 
        return f(); 
    return 1; 
}

您还假设所有节点都有零个或两个子节点。

如果采用空树中的所有项目都小于值的约定,则可以编写

template<class T>
bool all_less(TN<T>* t, T v)
{
    return !t
         || (  t->value < v
            && all_less(t->right, v)
            && all_less(t->left, v));
}

你的函数:

template<class T>
bool all_less(TN<T>* t, T v)
{
    if(v <= t->value) {
        return false;
    } else if(v > t->value) { // Why do you need this check?
        if(t->right != nullptr && t->left != nullptr) {
            // This is wrong because it's possible for one them to
            // nullptr while the other is not.
            all_less(t->right, v);
            all_less(t->left, v);
            // The above function calls are no op. You are calling
            // the function recursively but are ignoring the return
            // values.
        }
    }
    return true;
}

这应该有效:

template<class T>
bool all_less(TN<T>* t, T v)
{
   if(v <= t->value) {
      return false;
   }
   if(t->right != nullptr )
   {
      if ( !all_less(t->right, v) )
      {
         return false;
      }
   }
   if ( t->left != nullptr)
   {
      if ( !all_less(t->left, v) )
      {
         return false;
      }
   }
   return true;
}

附言:未经测试的代码。