Определить размер целого двоичного дерева с помощью рекурсии
у меня есть классы BinaryTreeNode(int value) с его левым и правым дочерним и BinaryTree (int rootVal) с корнем BinaryTreeNode с rootVal в качестве его значения. Я разработал код для вычисления количества узлов в дереве (в классе BinaryTreeNode), но он не работает из-за исключения NullPointerException:
public int size(){
if(this == null) { // base case
return 0;
} else {
return 1 + left.size() + right.size();
}
}
однако другое решение, которое я нашел, с аналогичной стратегией работает:
public int size(BinaryTreeNode refNode){
if(refNode == null) { // base case
return 0;
} else {
return 1 + size(refNode.left) + size(refNode.right);
}
}
Я понял, почему мой код выдает исключение (именно потому, что left / right будет указывать на null). Но я хотел бы понять, почему второе решение работает с квази тем же принципом. Заранее спасибо!
3 ответов
в первом примере вы пытаетесь найти размер, Прежде чем проверить null
:
сначала ты называешь
left.size()
и size()
способ проверить, чтобы увидеть, если объект вы назвали метод это null
if(this == null) { // base case
return 0;
...
если left
и null
, вы получаете NPE, прежде чем попасть в size()
метод.
главное, что нужно помнить здесь, это то, что this
can никогда быть null
. Если он был, во-первых, вы не можете использовать метод. Таким образом, вы фактически не завершали свою рекурсию на null
дело, как вы думали, что вы были.
во второй вы проверяете для null
первый:
если refNode.осталось null
здесь
return 1 + size(refNode.left) + size(refNode.right);
the size()
метод делает предварительную проверку
if(refNode == null) { // base case
return 0;
...
и благополучно возвращает 0
.
вы смогли сделать ваше первый метод работает, явно помещая нулевую проверку сначала в каждую ветвь:
public int size(){
return 1
+ left == null ? 0 : left.size() // check for null first
+ right == null ? 0 : right.size(); // check for null first
}
базовый случай организован неправильно; проверка на null
в текущем экземпляре нет смысла. Метод следует переписать следующим образом.
public int size(){
int sizeLeft = 0;
if (this.left != null)
sizeLeft = left.size();
int sizeRight = 0;
if (this.right != null)
sizeRight = right.size();
return 1 + sizeLeft + sizeRight;
}
this
не может быть null
внутри рабочего класса. Вы получите NPE, потому что узел с left == null
или right == null
не сможет назвать size()
код, потому что указатель не ссылается ни на что.
возможно, ваш код должен быть более оборонительным и проверять, являются ли дети нулевыми, прежде чем пытаться получить их размер:
public int size() {
int total = 1;
if (left != null)
total += left.size();
if (right != null)
total += right.size();
return total;
}