C++ 这个代码块[树]究竟是如何工作的?

C++ 这个代码块[树]究竟是如何工作的?,c++,tree,C++,Tree,下面的代码块究竟是如何工作的?更具体地说,程序如何知道返回哪个选项? return ancestor (node1->left(), node2) || ancestor (node1->right(), node2) || ancestor (node2->left(), node1) || ancestor (node2->left(), node1); 当树中给定节点1和节点2时,此代码块是遍

下面的代码块究竟是如何工作的?更具体地说,程序如何知道返回哪个选项?

return    ancestor (node1->left(), node2)
           || ancestor (node1->right(), node2)
           || ancestor (node2->left(), node1)
           || ancestor (node2->left(), node1);
当树中给定节点1和节点2时,此代码块是遍历树以确定一个节点是否为另一个节点的祖先的代码的一部分

请注意,节点1和节点2传递给负责确定是否存在可能的祖先/后代关系的函数:

bool ancestor (const Binary_node<Type> * node1, const Binary_node<Type> * node2)
{
         // .... code
}
bool祖先(常量二进制节点*node1,常量二进制节点*node2)
{
//……代码
}

如果对
祖先的调用之一返回true,它将返回true(不计算其余调用)。

从左到右计算术语,第一个为
true
的术语终止计算(快捷布尔计算)并返回
true
。否则,结果为
false

它从左到右求值,因此它首先测试祖先(node1->left(),node2)
。接下来,我们来看一下位运算符
|
,它的基本意思是,“如果上一个操作为false,那么尝试下一个操作”。

我猜您的函数会返回bool。如果其中一个祖先是真的,它将返回真。如果使用两个布尔值,结果如下:

A B (A || B) false false false true false true false true true true true true A B(A | | B) 假假假假 真假假真 假真真 千真万确
如果使用多个布尔值(或可以解释为布尔值的值),则
A | B | C..
等于
((A | B)| C)| C)
它将返回一个布尔值。因此,您所指的块只用于返回它找到的第一个
true
值,或
false
,如果它们都是这样计算的。

其中一条语句有几个由| |或&&链接的子句,则计算从左到右,第一次短路。在这种情况下,当使用| |时,该函数将从左到右(或在代码布局中从上到下)运行,当某个对象第一次计算为true时,它将返回true,从而避免计算其他选项。

请注意,祖先仅返回true/false。此代码使用早期逻辑表达式求值。在“或”(| |)语句中。若第一个调用并没有返回true,它将调用下一个调用,以此类推,直到其中一个返回true。如果它们都不返回true,则返回false

在这段代码中:如果我发现node1->left()是node2的祖先,我就不必计算语句的其余部分,因为我已经知道答案了

程序如何知道返回哪个选项

程序将继续尝试这些选项,直到找到一个可行的选项

下面的代码块究竟是如何工作的

在每次调用祖先()时,函数将尝试四种可能性:

  • 将node1移动到其左侧子树,并尝试完成问题的其余部分
  • 如果这不起作用,请尝试将节点1移动到其右侧子树
  • 如果这不起作用,请将node2移到其左子树
  • 如果这不起作用,请将node2移到其右侧子树
如果这四种可能性都失败了,那么节点node1和node2肯定不是通过祖先关系关联的


警告:在实现时,祖先函数非常慢,除了非常小的树。因为我们在每个祖先()调用中尝试了四个选项,如果将树的高度增加1,状态数大约会增加四倍。

这是一个多么可爱的递归。但是,如果node1是node2的祖先,则这是负责遍历树搜索的代码,反之亦然。。。它是如何通过前面提到的实现做到这一点的。。。0_其他可能还有其他地方,在那里使用的函数返回布尔值,不是吗?