【问题标题】:Recursive search on binary tree returning both true and false递归搜索返回真假的二叉树
【发布时间】:2015-02-02 03:29:15
【问题描述】:

对于一个赋值,我应该提出一个名为all_less 的递归函数,它接收一个指向any 任意树(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 truereturn false 之前放置了一些打印语句以查看发生了什么。

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

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

作为输入,会输出这个:

true
false
true
true

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

【问题讨论】:

  • 您正在递归调用all_less 并忽略返回值。为什么需要这些调用?

标签: c++ recursion tree binary-tree


【解决方案1】:

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

即使返回了一次错误,最终结果也会为真。

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));
}

【讨论】:

    【解决方案2】:

    你的功能:

    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;
    }
    

    附言未经测试的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-02
      • 2021-07-03
      • 2019-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      相关资源
      最近更新 更多