使用&&在一份退货声明中

时间:2014-09-25 03:08:41

标签: c++ return

我正在查看一个函数示例,该函数显示两个二叉搜索树是否是同构的(具有相同的形状)。在示例中,它返回两个语句。我很难理解这意味着什么。

bool isomorphic(struct treenode *treeone, struct treenode *treetwo)  
{  
    if (!treeone && !treetwo)  
        return true;    
    if((!treeone && treetwo) || (treeone && !treetwo))  
        return false;  

    return (isomorphic(treeone->left, treetwo->left)  
        && isomorphic(treeone->right, treetwo->right));  
}  

我遇到麻烦的部分是最后一句话。

上面的代码来自:http://tech-queries.blogspot.com/2010/04/isomorphic-trees.html

2 个答案:

答案 0 :(得分:4)

至少IMO,第一组陈述:

if (!treeone && !treetwo)  
    return true;    
if((!treeone && treetwo) || (treeone && !treetwo))  
    return false;  

......实际上比他们需要的更令人困惑,所以我开始简化它们。这基本上是检查我们是否已经到达一棵树或两棵树中的叶节点。如果树是相同的"形状",我们应该同时到达两个叶子节点。所以,这意味着如果其中任何一个是空指针,那么(从我们在这一点上可以看到),当且仅当两个都是空指针时,它们才具有相同的形状。

但请注意,只要我们在 树中找到空指针,我们就已经走得太远了 - 我们不需要进一步递归。要么它们都是空指针(所以我们返回true)或者其中一个是空指针而另一个不是指针(在这种情况下我们返回false)。

我们可以让这种逻辑更加明显。我想我会这样写:

if ((treeone == nullptr) || (treetwo == nullptr))
    return treeone == treetwo;

如果执行超过该点,则我们收到的指针都不是空指针。在这种情况下,当且仅当它们的子树是相同的形状时,树是相同的形状。那个可以写成这样的东西:

if (!isomorphic(treeone->left, treetwo->left))
    return false;

if (!isomorphic(treeone->right, treetwo->right))
    return false

return true;

但是,当且仅当两个子语句都返回true时,我们才返回true - 即,如果语句1为真,则语句2为真。我们可以将其缩写为逻辑and,如下所示:

return isomorphic(treeone->left, treetwo->left) 
   and isomorphic(treeone->right, treetwo->right));

然而,传统上,C和C ++已经使用&&作为逻辑 - 并且使我们回到最初找到它的语法。

但是,对于当前的C编译器,如果and,此代码应编译(使用&&而不是#include <iso646.h>)。在当前的C ++中,您甚至不必这样做(尽管可能必须使用一些特殊的命令行开关 - 例如,VC ++需要/Za)。

答案 1 :(得分:1)

第一个if语句检查传递给该函数的两个节点是否为NULL。 (如果两者都为NULL,则其同构,因此返回true)。

第二个if语句检查传递给该函数的其中一个节点是否为NULL。 (在这种情况下,显然它们不是同构的,所以返回假。)

此时函数知道传递给函数的两个节点都不是NULL。 这意味着传递给函数的前2个节点是有效的(意味着同构)

但你想知道的是整个树结构是否是同构的。所以这里最后一个return语句就是神奇的。

最后一个return语句是对函数本身的2次递归调用。 第一个递归调用检查左侧的节点是否是同构的。第二个是右侧。

此递归调用通过遍历节点来检查树中的所有节点。

我的建议是在笔记本中写一个树,然后逐步执行代码,看看会发生什么。