2014-12-21 2 views
0

Из двоичного дерева вы хотите создать 2-й arraylist, где каждый arraylist в основном arraylist содержит все узлы двоичного дерева на одном уровне для всех уровней. Я понимаю, как это сделать рекурсивно с DFS, но я очень смущен тем, почему можно получить правильный ответ, передав в arraylist, который я хочу заполнить как параметр в рекурсивной функции.Значение параметра рекурсии Java Значение

Заголовок моей рекурсивной функции выглядит следующим образом

createLevelLinkedList(TreeNode current, ArrayList<LinkedList<TreeNode>> lists, int level) 

С basecase:

if (current == null) return; 

Как дерево проходится, текущий узел будет добавлен в соответствующий 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

Вы не указали код, в который вы добавляете узлы в свой список, так как мы можем ответить на ваш вопрос? Почему бы вам не опубликовать полный код 'createLevelLinkedList'? – Eran

+0

Да, конечно. Я просматриваю код на GitHub https://github.com/gaylemcd/ctci/blob/master/java/Chapter%204/Question4_4/QuestionDFS.java –

ответ

1

Вы должны понимать, что есть только один ArrayList экземпляр передается методу createLevelLinkedList. Каждый рекурсивный вызов createLevelLinkedList получает ссылку на тот же экземпляр ArrayList.

Поэтому, как только TreeNode 2 добавляют к ArrayList (или, точнее, к одной из LinkedList с содержащимися в ArrayList), он остается там в течение выполнения рекурсивного метода. Он не исчезает, когда возвращается значение createLevelLinkedList, которое добавило его в список.

+0

Я вижу. Я думаю, что моя основная путаница исходит из 'level', не меняющего значения в предыдущих кадрах стека после добавления' TreeNode'2 в 'lists'. Это потому, что уровень является примитивным типом? –

+1

@ArjunPatel Java - это пароль по языку значений, поэтому не имеет значения, передаете ли вы примитивную или ссылочную переменную методу. В обоих случаях метод может изменять локально только локально, что не влияет на предыдущие кадры стека. Переменная 'lists' также остается неизменной. Вещью, которая изменяется, является состояние объекта 'lists' (поскольку вы добавляете к нему связанные списки и элементы). – Eran

Смежные вопросы