【问题标题】:Binary Search Tree Recursion Confusion二叉搜索树递归混淆
【发布时间】:2017-05-08 17:55:13
【问题描述】:

我认为这是一个愚蠢的问题,但很遗憾地说它会清除我的困惑。 如果您只是查看此代码

void printInOrder(){
        printPrivateInOrder(root);
    }
void printPrivateInOrder(Node* n){
        if (root != NULL){
            if (n->left != NULL){
                printPrivateInOrder(n->left);
            }
            cout << n->val << " ";
            if (n->right != NULL){
                printPrivateInOrder(n->right);
            }
        }
        else{
            cout << "Tree is Empty\n";
        }
    }

在这个 Traversal 中,如果我们去到最左的孩子,那么这个函数又是如何被调用的呢?假设只看图片 BST Example 我们已经移动到节点 4,那么如何再次调用这个函数呢?如果两个孩子都是空的,我不会再次调用此函数,而是再次调用此函数并打印 InOrder Traversal 中的所有节点?怎么样?

【问题讨论】:

    标签: pointers recursion data-structures binary-search-tree traversal


    【解决方案1】:

    当您递归到下一个级别时,这基本上涉及拍摄您所在位置的快照,然后开始做其他事情。一旦完成“其他事情”,您将返回快照并继续。

    这与调用递归函数非常相似。当一个函数调用xyzzy() 时,它确切地知道调用返回时从哪里继续。递归函数是相同的,只是它们都在向下和备份的过程中通过相同的段代码。

    所以,当你回到一个关卡(例如,已经处理了左边的节点),你将打印当前节点,然后下到子的右边树。

    考虑示例树:

      2
     / \
    1   4
       / \
      3   5
           \
            6
    

    要处理这棵树,对于每个节点(从两个开始),您处理左侧节点,打印当前节点值,然后处理右侧节点。

    但是,您需要了解“处理左/右节点”是在其中一个子节点上再次执行的整个“处理左侧、打印当前、处理右侧”步骤集。从这个意义上说,处理根节点和处理任何其他节点之间没有区别。

    “处理”是按顺序打印给定点(包括该点)下的所有节点。如果你从根节点开始,你会得到整棵树,这只是一个令人高兴的效果:-)

    因此,就实际发生的情况而言,它基本上遵循递归路径:

      2, has a left node 1, process it:
      |  1, has no left node.
    > |  1, print 1.
      |  1, has no right node.
      |  1, done.
    > 2, print 2.
      2, has a right node 4, process it.
      |  4, has a left node 3, process it.
      |  |  3, has no left node.
    > |  |  3, print 3.
      |  |  3, has no right node.
      |  |  3, done.
    > |  4, print 4.
      |  4, has a right node 5, process it.
      |  |  5, has no left node.
    > |  |  5, print 5.
      |  |  5, has a right node 6, process it.
      |  |  |  6, has no left node.
    > |  |  |  6, print 6.
      |  |  |  6, has no right node.
      |  |  |  6, done.
      |  |  5, done.
      |  4, done.
      2, done.
    

    如果您检查每条打印线(请参阅&gt; 标记),您会看到它们以所需的顺序出现。

    【讨论】:

    • 你的答案太棒了,它的工作方式和你说的一样,但是,如果我再回头看2, has a left node 1, process it: 1, has no left node. 1, print 1. 1, has no right node. 2, print 2. 2,有一个左节点 1,我们移动到 1,我们处理了 1,但是我们如何回到 2 并打印 2?你能进一步解释一下吗@pexdiablo
    • @Fawad,我已经修改了前几段以希望澄清。您知道返回并打印2 的方式是因为递归行为会保存您当前的状态以供以后恢复。
    猜你喜欢
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    • 2014-01-02
    • 2021-07-03
    • 2019-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多