код в моем операторе else мертв, и я не верю, что это правда (java)?

Я работаю с организованным BST в своем java-коде. Предполагается, что эта функция/метод ищет в дереве узел с определенным значением и сообщает пользователю, существует ли он или нет.

    void search(int item, Node root, int r, int c) {

        //if the integer is found
        if(root.val == item) {
            System.out.println("integer located at row: " + r + " & child: " + c + "\n");
        }

        //if the integer is not found (use the closest value to find it)
        else if(root != null) {
            if(item < root.val) 
                search(item, root.left, r + 1, (c * 2) - 1);
            else
                search(item, root.right, r + 1, c * 2);
        }

        //if the root is a null (it doesn't exist or cannot be found)
        else {
            System.out.println("integer cannot be located\n");
        }
    }

Проблема в операторе else в конце. Мой компилятор говорит, что все в этом операторе else является мертвым кодом, то есть не используется. Однако мне нужен код в этом операторе else на тот случай, если функция обнаружит нулевое значение и не сможет найти узел с присвоенным значением. Это исчезнет, ​​если я изменю второй оператор else на else if(root.val != item && root != null), но это заставит меня задаться вопросом, есть ли точка, в которой root не будет равен нулю, я знаю, что это должно быть возможно. Является ли оператор else действительно мертвым кодом, и если это так, как я могу это изменить?


person mario segale    schedule 08.02.2020    source источник
comment
else if (root != null) подозрительно. В if осуществляется доступ к root.val. Если бы root было null, было бы выброшено NullPointerException. Таким образом, если достигнуто else if, оно всегда будет вводиться. Таким образом, последнее else никогда не будет введено. Я бы предположил, что внешний if должен быть первым if во внешнем else if, а внешний else if должен быть if.   -  person Turing85    schedule 09.02.2020
comment
Если root имеет значение null, ссылка на root.val вызовет исключение в первом if. Таким образом, ненулевая проверка в первом else не нужна. При столкновении с подобными проблемами первое предположение никогда не должно заключаться в том, что компилятор, используемый миллионами, должен быть неверным. Проблема всегда в вашем коде.   -  person Torben    schedule 09.02.2020
comment
Короче говоря, компилятор довольно умный.   -  person MC Emperor    schedule 09.02.2020


Ответы (2)


Ваше первое if выражение:

if (root.val == item)

либо выдаст NullPointerException, если root равно null, либо выполнит сравнение, если нет. Следовательно, последний блок else никогда не может быть выполнен.

Вы можете попробовать изменить порядок кода:

void search(int item, Node root, int r, int c) {
    if (root != null) {
       if (root.val == item) {
           System.out.println("integer located at row: " + r + " & child: " + c + "\n");
       } else if (item < root.val) {
            search(item, root.left, r + 1, (c * 2) - 1);
       } else {
            search(item, root.right, r + 1, c * 2);
       }
    } else {
       System.out.println("integer cannot be located\n");
    }
 }
person dave    schedule 08.02.2020
comment
Я забыл о NullPointerException. Спасибо - person mario segale; 09.02.2020

Это мертвый код, потому что разыменование root в root.val требует, чтобы root был не-null. Если бы это было null, вы бы получили NullPointerException.

В моей среде IDE это предупреждение; код синтаксически правильный, но с точки зрения семантики последняя цифра else никогда не будет введена.

Чтобы решить эту проблему, сначала проверьте null в выражении if:

void search(int item, Node root, int r, int c) {
    if (root == null) {
        // if the root is a null (it doesn't exist or cannot be found)

        System.out.println("integer cannot be located\n");
    } else if (root.val == item) {
        // if the integer is found

        System.out.println("integer located at row: " + r + " & child: " + c + "\n");
    } else if (item < root.val) {
        // if the integer is not found (use the closest value to the left to find it)

        search(item, root.left, r + 1, (c * 2) - 1);
    } else {
        // if the integer is not found (use the closest value to the right find it)

        search(item, root.right, r + 1, c * 2);
    }
}

Обратите внимание, что вы можете изменить первые два if таким образом, чтобы они напрямую возвращали или останавливали выполнение метода. Тогда проверка item < root.val не обязательно должна находиться в блоке else. Чем неглубокее ваши операторы if, тем лучше (но всегда используйте фигурные скобки для каждого блока!).

person Maarten Bodewes    schedule 08.02.2020
comment
почему не else if (item < root.val)? Я не понимаю, почему дополнительный блок (если только не сохранить код OP) - person user85421; 09.02.2020
comment
Хороший вопрос, я думаю, что я только что читал об этом, это было в org. код, и это не было ошибкой как таковой. - person Maarten Bodewes; 09.02.2020
comment
Я думаю, было бы еще красивее, если бы я заменил == на > для симметрии, а затем обработал найденный вариант последним, но да, на сегодня достаточно ветвления. - person Maarten Bodewes; 09.02.2020