用Java将二叉树展平为数组
我在Java中找到了将二叉树展平为数组的方法。我很难理解它是如何工作的 代码如下:用Java将二叉树展平为数组,java,arrays,algorithm,binary-tree,functional-programming,Java,Arrays,Algorithm,Binary Tree,Functional Programming,我在Java中找到了将二叉树展平为数组的方法。我很难理解它是如何工作的 代码如下: private static int FlattenTreeIntoArray(Node tree, int[] array, int i) { if (tree == null) return i; // Flatten left subtree i = FlattenTreeIntoArray(tree.Left, array, i); // Get data from the
private static int FlattenTreeIntoArray(Node tree, int[] array, int i)
{
if (tree == null) return i;
// Flatten left subtree
i = FlattenTreeIntoArray(tree.Left, array, i);
// Get data from the current node
array[i] = tree.Data;
// Flatten right subtree
i = FlattenTreeIntoArray(tree.Right, array, i + 1);
return i;
}
我的问题如下:
int[]array
和int i
)?我们不知道二叉树的大小树
为null
时,它返回i
。这是什么意思i+1
传递到右树
,而将i
传递到左树
int i
是数组中的索引-您希望从0开始,因为它是第一个元素。如果您不知道树的大小,最好使用LinkedList
How does the method function: when the tree is null, it returns i. what does that mean?
这意味着您正在检查一个不存在的“子项”,因此您返回的索引不变
扁平化是如何发生的?为什么i+1被传递到右树,而我
到左边的树
您将i传递到左树,因为该调用将通过递归证明传回树中当前节点上的数据所属的索引。然后必须告诉右树索引已增加,因为根据定义,右树中的任何内容的值都将高于当前节点
您的调用将是platteTreeInToArray(my_tree,my_array,0)
wheremy_array.length==9
在第一次调用时,左子树是根节点3
,它通过索引0。调用左子树后,new左子树是一个包含数据1的叶子。当以1作为根调用FlattTreeInToArray
时,它将向FlattTreeInToArray
传递一个空子级,从而返回0
您的下一个调用将是my_array[0]=1
,因此数组的第一个元素是树中的最低数字。然后它将递增并返回索引
因此,最终根为3的调用将返回
1
作为索引,并将调用my_array[1]=3
。诸如此类,冲洗并重复。这是一个简单的递归示例,一旦理解了这一点,所有递归树算法都应该开始有意义了。我将尽力回答您的问题:
这是helper方法,实际的方法是如何调用的,或者什么作为参数传递给int i和int[]数组--我们不知道二叉树的大小
查看代码,由于这是一个面试类型的问题,我们将假设int[]数组足够大,可以容纳所有内容
i
似乎是要填充的数组的当前索引,因此展开树的第一个调用将i
设置为0
此方法还返回一个整数,该整数是到目前为止已填充的元素数。这意味着最终返回将返回树的全长(以及数组中填充的元素数)
该方法如何工作:当树为null时,它返回i。这是什么意思?
这假设如果没有子节点,节点的左或右字段指向null。由于我们使用i
来维护我们在数组中的位置,因此如果没有子级,我们不会更新i
的值
扁平化是如何发生的?为什么i+1传递到右树而i传递到左树。
通过找到最左边的节点并将其放入i
,可以实现展平。然后找到下一个最左边的节点并将其放入i+1
等
让我们浏览一下您给出的树示例:
节点=8
i=0;
数组={}
获取根的左节点(3)并递归调用此展平方法,该方法获取3的左节点(1),当获取1的左节点(null)时,再次递归调用展平方法。返回i
=0。
现在我们使用的是节点1的展平方法array[0]=节点1的值=`array[0]=1
现在调用节点1的右字段并展平递增的i。节点1的右字段为null,因此我们返回i的当前值(即1)
现在我们回到节点1的展平方法中,找到了左、右递归,并到达了方法的末尾,因此我们返回当前值i
,即1
现在我们回到节点3的展平方法。我们刚刚完成了对左字段的展平方法的调用,该方法返回的值为1,现在我们将i设置为
现在我们用节点3的值更新数组
array[1] = 3;
现在我们用递增的i soi=2展平节点3的右字段(节点6)
等
希望对你有所帮助除了其他答案,我还制作了这个gif来演示算法的执行。您可以在左侧看到必须处理的元素,在右侧看到数组
这是一个非常实用的代码(请参阅)。这种类型的树遍历称为
让我们做一些观察
这棵树只是被阅读,从未被改写过
在每个调用中,i
仅递增一次,前提是当前节点不为null<代码>i
从不递减
数组
仅写入。唯一的写入是在索引i
上。不使用数组执行任何其他操作(传递其引用除外)
当前节点数据在处理左子树和右子树之间写入数组
array[1] = 3;
// tree and MAX_TREE_SIZE come from outside
int[] array = new int[MAX_TREE_SIZE];
int tree_size = FlattenTreeIntoArray(tree, array, 0);