2017-02-16 31 views
1

Я пытаюсь понять, почему вывод консоли застрял в бесконечном цикле на листе, когда я использую вместо этого, если в коде ниже.Обход порядка двоичного дерева. Если vs while

void preOrder(Node root) { 
    Node n = root; 
    while(n != null) { 
     visit(n); 
     preOrder(n.left); 
     preOrder(n.right); 
     } 
    } 

Когда рекурсивная функция для предзаказа вызывается в лист, лист не имеет левый child.Shouldn't выполнение останавливается.

ответ

2

Проблема заключается в том, что при наличии while(n != null) вы никогда не переназначаете n тому, что потенциально может быть не null, и таким образом вы получите бесконечный цикл.

if утверждение, что вам нужно, потому что у вас уже есть рекурсивные вызовы, которые будут перемещаться по дереву вверх, пока лист не найден:

Node n = root; 
if (n != null) { 
    visit(n); 
    preOrder(n.left); 
    preOrder(n.right); 
} 
3

while(n != null) всегда будет истинным или никогда не будет истинным, так как тело цикла не изменит значение n. Следовательно, цикл никогда не будет выполняться или быть бесконечным.

Поскольку вы используете рекурсию, вам не нужен цикл.

void preOrder(Node root) { 
    Node n = root; 
    if (n != null) { 
     visit(n); 
     preOrder(n.left); 
     preOrder(n.right); 
    } 
} 

Когда рекурсивная функция для предзаказа вызывается в лист, лист не имеет левый не child.Shouldn't исполнение останавливается

Ну, выполнение preOrder(n.left) прекращается (поскольку n.left имеет значение null), но затем он вернется к предыдущему вызову preOrder и вызовет preOrder(n.right), и если этот вызов завершится, он будет застревать в бесконечном цикле while.

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