在二叉树中,您需要创建一个二维arraylist,其中主arraylist中的每个arraylist包含所有级别的单个级别上的二叉树的所有节点。我理解如何使用DFS递归执行此操作,但我很困惑为什么可以通过传递我希望在递归函数中填充的arraylist来获得正确的答案。
我的递归函数的标题看起来像这样
createLevelLinkedList(TreeNode current, ArrayList<LinkedList<TreeNode>> lists, int level)
使用basecase:
if (current == null) return;
当遍历树时,当前节点将被附加到“lists”中对应的arraylist。在递归函数中,有两个递归调用将函数移动到当前的子节点:
createLevelLinkedList(current.left, lists, level + 1);
createLevelLinkedList(current.right, lists, level + 1);
假设有一棵树看起来像这样
5
3 8
2 4 9
使用深度优先树遍历,在第一次返回之后,我们将使TreeNode“2”成为堆栈中的顶级对象,然后是“3”。当TreeNode“3”为当前且函数调用
时 createLevelLinkedList(current.right, lists, level + 1);
要将TreeNode“4”推入堆栈,如果实际上包含TreeNode“2”以及内存中实际发生了什么,它们如何包含?
我引用的代码可以在Github上找到:https://github.com/gaylemcd/ctci/blob/master/java/Chapter%204/Question4_4/QuestionDFS.java
public static void createLevelLinkedList(TreeNode root, ArrayList<LinkedList<TreeNode>> lists, int level)
{
if (root == null) return;
LinkedList<TreeNode> list = null;
if (lists.size() == level) { // Level not contained in list
list = new LinkedList<TreeNode>();
/* Levels are always traversed in order. So, if this is the first time we've visited level i,
* we must have seen levels 0 through i - 1. We can therefore safely add the level at the end. */
lists.add(list);
} else {
list = lists.get(level);
}
list.add(root);
createLevelLinkedList(root.left, lists, level + 1);
createLevelLinkedList(root.right, lists, level + 1);
}
答案 0 :(得分:1)
您应该了解,只有一个ArrayList
实例传递给createLevelLinkedList
方法。每次递归调用createLevelLinkedList
都会收到对ArrayList
的同一实例的引用。
因此,一旦将TreeNode
2添加到ArrayList
(或者,确切地说,添加到LinkedList
中包含的ArrayList
之一),在整个递归方法的执行过程中保持不变。当将createLevelLinkedList
添加到列表中的{{1}}的调用返回时,它不会消失。