【问题标题】:Can someone explain to me this recursive code for binary tree?有人可以向我解释这个二叉树的递归代码吗?
【发布时间】:2018-04-21 00:35:28
【问题描述】:

我正在尝试解决“二叉树颠倒”这个问题。例如,如果我们有一棵二叉树:

    1
   / \
  2   3
 / \
4   5

运行我的函数后,会变成:

   4
  / \
 5   2
    / \
   3   1 

我得到了以下递归代码,但无法理解 //1 和 //5 之间的步骤;

public TreeNode UpsideDownBinaryTree(TreeNode root)
{
    if (root == null) return null;

    TreeNode parent = root, left = root.left, right = root.right;
    if (left != null)
    {
        TreeNode ret = UpsideDownBinaryTree(left); //1
        left.left = right;   //2
        left.right = parent; //3
        return ret;          //4
    }
    return root;             //5
}

有人可以详细解释一下每个步骤在这里做什么吗?另外,为什么我们有两个单独的返回:return retreturn root

我知道如何对常规数组、列表和一些二叉树进行递归。但是这个递归逻辑似乎和我之前知道的不一样。我什至用IDE单步执行,但还是不能完全理解。

对于这个问题,我也有以下迭代代码。我可以理解这段代码。它从根扫描树到离开。但是对于递归代码,它是从根到叶扫描树并从叶到根构建新树?我理解正确吗?

public TreeNode UpSideDownTree_Iterative(TreeNode root)
    {
        TreeNode node = root,parent = null,right = null;
        while (node != null) {
            TreeNode left = node.left;
            node.left = right;
            right = node.right;
            node.right = parent;
            parent = node;
            node = left;
        }
        return parent;
}

【问题讨论】:

标签: recursion binary-tree


【解决方案1】:

从最后一次调用向后看可能会有所帮助。
该方法使用左节点递归调用,因此将使用节点 1,2 和 4 调用。
最后一个左节点(叶子)是节点 4 : 见 cmets:

//when invoked with node 4 
public TreeNode UpsideDownBinaryTree(TreeNode root)
{
    if (root == null) return null;

    TreeNode parent = root;      //node 4 
    TreeNode leftNode = root.left;   //null  
    TreeNode rightNode = root.right; //null  

    if (leftNode != null) 
    {
        //not executed
        TreeNode ret = UpsideDownBinaryTree(leftNode); //invoke with 2
        leftNode.left = rightNode; //left of node 2 becomes node 3
        leftNode.right = parent; //right of node 2 becomes 1
        return ret;          
    }
    return root;             //returned. The leaf becomes new root
}

让我们看一下上一步:它返回到上一个调用(节点2):

//when invoked with node 2 
public TreeNode UpsideDownBinaryTree(TreeNode root)
{
    if (root == null) return null;

    TreeNode parent = root;       //node 2 
    TreeNode leftNode = root.left;   //node 4  
    TreeNode rightNode = root.right; //node 5 

    if (leftNode != null) 
    {
        TreeNode ret = UpsideDownBinaryTree(leftNode); //invoke with node 4
                                                       //as seen above return 
                                                       //value is node 4 
                                                       //which is the new root
        leftNode.left = rightNode; //left of node 4 becomes node 5
        leftNode.right = parent; //right of node 4 becomes 2
        return ret; //node 4 returned, the new root        
    }
    return root;            
}

第一次调用(节点 1),与节点 2 非常相似。

【讨论】:

  • 感谢您的解释。这很有帮助,我想我更好地理解它。有没有其他递归方式来实现这个功能?我只是想做一些比较以便更好地理解它。
  • 请在单独的帖子中发布其他问题(“还有其他递归方式来实现此功能吗?”)。这里可能更合适:codereview.stackexchange.com
猜你喜欢
  • 1970-01-01
  • 2021-08-06
  • 1970-01-01
  • 2018-07-23
  • 1970-01-01
  • 2011-08-20
  • 1970-01-01
  • 2022-12-16
  • 2021-12-24
相关资源
最近更新 更多