有人可以向我解释这个二叉树的递归代码吗?
Can someone explain to me this recursive code for binary tree?
我正在尝试解决这个问题"Binary tree upside down"。例如,如果我们有一个二叉树:
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
}
有人可以详细解释一下这里的每一步是做什么的吗?另外,为什么我们有两个单独的returns:return ret
、return 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;
}
从上次调用倒过来看可能会有帮助。
该方法是用左节点递归调用的,因此它将用节点 1,2 和 4 调用。
最后一个左节点(叶子)是节点 4 :
查看评论:
//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
}
让我们看一下上一步:returns 到上一个调用(节点 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 非常相似。
我正在尝试解决这个问题"Binary tree upside down"。例如,如果我们有一个二叉树:
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
}
有人可以详细解释一下这里的每一步是做什么的吗?另外,为什么我们有两个单独的returns:return ret
、return 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;
}
从上次调用倒过来看可能会有帮助。
该方法是用左节点递归调用的,因此它将用节点 1,2 和 4 调用。
最后一个左节点(叶子)是节点 4 :
查看评论:
//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
}
让我们看一下上一步:returns 到上一个调用(节点 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 非常相似。