我在理解这个代码片段的核心方面遇到了一些实际困难,尽管它看起来非常简单明了。给定一个简单的二叉树,这个着名的函数会产生同一棵树的镜像结果。
void mirror(struct node* node) {
if (node==NULL) {
return;
}
else {
struct node* temp;
// do the subtrees
mirror(node->left); //this part confuses me
mirror(node->right); //so does this
// swap the pointers in this node
temp = node->left;
node->left = node->right;
node->right = temp;
}
}
这将是代码。读完这段代码后,我脑子里有两个问题。
mirror(node-> left)和mirror(node-> right)在调用堆栈上放置两个连续的函数调用。我的理解是,首先, 函数在左侧节点上调用,然后在右侧调用。这个流程 只要节点为空,就会重复。但是当它不是空的时候会是什么 它回归?它是否只是回到call语句中 什么都归还?
如何从调用堆栈调用这些函数?这将是 如果有人通过函数调用并告诉我真的很有帮助 我们如何以及为什么需要连续两次函数调用。
P.S:为什么在这个范围内没有使用迭代?
编辑:引用EOF的有用评论,是否有可能进行尾部递归 这个函数是通过在两个递归调用之前移动交换?
答案 0 :(得分:2)
- 醇>
mirror(node->left)
和mirror(node->right)
在调用堆栈上放置两个连续的函数调用。
这是一种奇怪的方式,它可能反映出一种误解。在任何时候,调用堆栈都不包含两个这些函数调用的表示。
我的理解是,首先,在左侧节点上调用该函数,然后调用右侧。只要节点为空,此过程就会重复。但是当它不是空的时候它会返回什么?
该函数的类型为void
。它永远不会返回任何东西。
它是否只是在没有返回任何内容的情况下返回到调用语句?
是的,当函数完成时,控制将在函数调用后的下一个语句中恢复。
- 如何从调用堆栈调用这些函数?
醇>
未调用"来自"调用堆栈。堆栈帧是为函数创建的,并在调用函数的过程中被推送。细节未指明;编译器负责生成代码以做正确的事情。
如果有人通过函数调用并告诉我们如何以及为什么需要两个连续的函数调用,那将非常有用。
镜像整个树意味着反转每个节点的子节点。因此,在处理给定节点时,该函数必须确保该节点的子节点都被镜像。它通过对每个执行递归调用来实现,然后交换它们。
答案 1 :(得分:1)
所以这里发生的事情是mirror()函数以后期顺序执行镜像操作。也就是说,处理左子树,然后处理右子树,然后处理父节点。所以它首先做的是检查当前节点是否为空。
if (node == null) {
return;
}
仅在到达叶节点后才会发生这种情况。叶节点具有空左右指针,因此当它执行镜像(节点 - >左)时它将有效地执行镜像(空)。与右节点一样。由于节点为空(例如,这是叶节点的左或右指针),因此无需执行任何操作。
对镜像(节点 - >左)和镜像(节点 - >右)的调用导致处理左子子树和右子子树。完成后,左右指针在当前节点中交换,镜像过程完成。