这是preOrder遍历的代码 -
void preOrder(node *root)
{
if(root!=NULL)
{
cout<<root->data<<" ";
preOrder(root->left);
preOrder(root->right);
}
}
当我们到达左边的最后一个节点时,它是如何进入正确的节点的?我的意思是左右节点之间没有链接虽然它们都有相同的父节点但是在到达最后一个节点之后它又如何返回到它的父节点?
答案 0 :(得分:2)
是的!在同一节点的两个子节点之间没有direct
链接。
现在为了帮助您解决上面的递归代码,请查看以下来自geeksforgeeks的图片。
直接跳到最左边的节点 4 ,因为你知道你是如何到达那里的,现在让我们了解它是如何移回其父节点的,依此类推。
当你出现以下行时,由于if(root!=NULL)
左边的孩子和4
的右孩子是空的,你肯定会出现这种情况,仍然没有得到它?别担心,请参阅以下说明。
现在,在最左边的节点4
,在这种情况下,负责到达此节点的行是:
preOrder(root->left)
你到目前为止还没有看到这条线下面的东西
即。你从未见过以下这一行:
preOrder(root->right);
。
4
的左子是null
,因此递归条件会中断,你最终会看到preOrder(root->right);
。这不是某种巫术,这就是递归。现在,当您看到4
的正确孩子又是null
时。
嗯,现在 root 的价值是多少?
root 的值为2
,因为2
是唯一一个将您带到4
的值。递归就像一个级别内的级别,当最后一个级别结束时,该调用将返回到它之上的级别,2
为4
。最后,以下行将把它带到2
5
的正确孩子。
preOrder(root->right);
带走:
1)每当您看到cout<<root->data<<" ";
时,就会打印当前根的值。
2)每当你看到preOrder(root->left);
移动到root的左边孩子时。
3)每当你看到preOrder(root->right);
时,你就会移动到正确的根孩子身上。
4)如果root的值为NULL
,则不会执行任何操作,您将被带回调用行,该调用行将是preOrder(root->left);
或preOrder(root->right);
。
如果我们按照上面的说法进行操作,您可以猜测给定二叉树的preOrder遍历将是:
1 2 4 5 3
现在,我建议您阅读并学习递归,然后再次解决上述问题。
答案 1 :(得分:0)
您正在递归调用该函数。每次调用preOrder
都会在线程的执行堆栈上创建我们称之为帧的内容。这些帧遵循树中的每个路径。当你从函数中return
时,它的调用框架被从堆栈中移除(或“弹出”),控件返回到前一帧。
这就是为什么当你到达一片叶子时,你“回溯”到父母,然后再回到兄弟子树(通过第二次调用preOrder
)。您谈到的“链接”实际上是在执行堆栈上创建的。