2014-09-25 42 views
0

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

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

+1

不清楚是什么让你觉得它'返回两个陈述'。它看起来是一段简单的代码,有三种可能的执行路径。也许不正确的缩进让你感到困惑? – 2014-09-25 03:14:50

+1

@Chantola _“不要!停止编码!没有希望!”_这当然不是正确的反应方式!即使这是一个很糟糕的问题,也没有理由欺负或步入人体。留在本网站专业的语气! _(我已将您的评论标记为粗鲁/令人反感,未来将不再受到禁令)_ – 2014-09-25 03:25:08

回答

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 - 也就是说,if语句之一为真语句包含两个是真的。我们可以缩写是到一个逻辑and这样的:

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

传统,然而,C和C++已经使用&&的逻辑和,这会让我们回到语法您最初发现它。

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

+0

非常感谢。我从来没有看到它以这种方式使用,而且我的教授在回答问题方面非常好。但她以另一个问题的形式回答了他们,所以我问她关于他们的问题,然后她回答说:“好吧,这不是对两个不同数据类型的两个未知值进行简单比较” 反正非常感谢你寻求帮助。 – 2014-09-25 16:02:55

1

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

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

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

但是你想知道的是如果整个树结构是同构的。所以这里的最后一个回报声明是这样的。

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

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

我的建议是在笔记本上写一棵树并逐步执行代码,看看会发生什么。