在返回语句中使用 &&
Using && in a return statement
我正在看一个函数的例子,该函数显示两个二进制搜索树是否同构(形状相同)。在该示例中,它返回两条语句。我很难理解这意味着什么。
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
至少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
——也就是说,如果语句一为true,并且语句二为true。我们可以将其缩写为逻辑and
,如下所示:
return isomorphic(treeone->left, treetwo->left)
and isomorphic(treeone->right, treetwo->right));
然而,传统上,C和C++使用&&
作为逻辑和,这让我们回到了最初的语法
然而,使用当前的C编译器,如果您使用#include <iso646.h>
,则应该编译此代码(使用and
而不是&&
)。在当前的C++中,您甚至不必这样做(尽管可能必须使用一些特殊的命令行开关——例如,VC++需要/Za
)。
第一个if语句检查传递给函数的两个节点是否为NULL。(如果两者都为NULL,则同构因此返回true)。
第二个if语句检查传递给函数的节点之一是否为NULL。(在这种情况下,显然它们不是同构的,所以返回false。)
此时,函数知道传递给函数的两个节点都不是NULL。这意味着传递给函数的前2个节点是有效的(意味着同构)
但你想知道的是,整个树结构是否同构。所以这里最后一个return语句起到了神奇的作用。
最后一条返回语句是对函数本身的2次递归调用。第一个递归调用检查左侧的节点是否同构。第二个是右边的。
这个递归调用通过遍历节点来检查树中的所有节点。
我的建议是在笔记本上写一棵树,一步一步地执行代码,看看会发生什么。
- 返回语句后的代码,没有警告
- 三元运算符在返回语句中给出意外的结果
- 返回非 void 的函数中没有返回语句警告
- 如何使用单个返回语句返回对变量的引用
- 当返回语句时,逗号运算符、大括号初始化列表和 std::unique_ptr 组合在一起
- 获取上次执行的返回语句的行
- 返回语句中矢量初始化时出现编译错误
- 快速搜索链表未编译,需要返回语句
- 静态成员函数赋值而不带返回语句
- 在返回语句中构造对象时,std::move() 是否有助于或阻止 RVO?
- 为什么返回语句和打印语句返回不同的答案?
- C++ 非 void 函数的崩溃没有返回语句
- 在返回语句中嵌套条件运算符
- 为什么结构化绑定禁用RVO和移动返回语句
- C - 程序返回值而无需返回语句
- 返回语句中的构造函数语法
- 编译器遇到返回语句时会做什么
- 是一个单一的返回语句清洁器
- C NRVO/复制Elision在括号中带有返回语句
- C 编译器 - 被遗忘的返回语句