Метод K [] preOrder() бинарного дерева поиска: об общем возврате

#java #generics #data-structures #binary-search-tree

#java #общие #структуры данных #binary-search-tree

Вопрос:

Использование реализации: лабораторное упражнение по структуре данных за октябрь / 28 / 2011 Что нужно сделать: реализовать бинарное дерево поиска

Проблема: K [] возврат методов preOrder(), inOrder() и postOrder()

Детально проблема: по британскому летнему времени, должно быть только его корень в качестве параметра. Вышеупомянутые методы были описаны в интерфейсе, предоставленном нашим профессором, следующим образом:

     /**
    * Returns an array of keys filled according
    * to the pre-order traversing in a BST.  
    */      
    public K[] preOrder();      
    public K[] order();         
    public K[] postOrder();
  

Я мог бы создать экземпляр универсального массива с помощью следующего кода:

 public K[] preOrder() {

    if (root == null) { return null; }

    ArrayList<K> list = new ArrayList<K>();
    preOrderRecursive(root,list);
    K[] toReturn = (K[]) Array.newInstance(this.getRoot().getKey().getClass(), list.size());

    for (int i = 0; i < list.size(); i  ) {
        toReturn[i] = list.get(i);
    }

    return toReturn;
}
  

Но, когда я тестировал метод с использованием испытательной класса также указана на нашем профессор, я получил исключение NullPointerException, который я думаю, имеет в виду корень по британскому летнему времени, что был когда-то создан, но был удален на стадии тестирования, и когда он вызывает метод снова, метод возвращает значение null, а не пустой массив, как и ожидалось с помощью теста:

     (...)

    tree1 = new BSTImpl<Integer, Integer>();
    for (int i = 0; i < SIZE; i  ) {
        tree1.insert(i, i);
    }
    tree1.remove(1);
    tree1.remove(2);
    tree1.remove(3);
    tree1.remove(4);
    assertArrayEquals(new Integer[]{},tree1.preOrder());

    (...)
  

Зная, что я не могу изменить ни возвращаемый тип, ни параметры метода, что я могу сделать, чтобы избежать этого исключения? Могу ли я каким-то образом получить тип компонента и использовать его для создания экземпляра пустого массива (как я это сделал?)?

Также приветствуются любые советы по улучшению моего кода.

Комментарии:

1. Вы используете array.size в своем newInstance выражении при создании массива, но не уверены, к чему array относится. Затем вы переходите к использованию list.size() для заполнения K[] . Вы убедились, что на самом array.size деле имеет ненулевую длину?

2. это была простая ошибка: я использовал имя переменной «array», чтобы назвать список, когда я размещал здесь, я переименовал все переменные в самоописывающееся имя, но забыл переименовать его там. выражение «array.size()» относится к списку, а не к массиву.

Ответ №1:

Вопрос: вам действительно нужен возвращаемый целочисленный массив? — Я так не думаю.

Я предполагаю assertArrayEquals() , что не проверяет тип компонента массивов, а только сравнивает содержащиеся значения.

С помощью кода, который вы показали, я бы сказал, что все остальное было бы невозможно из-за стирания типа.

Поэтому попробуйте вернуть Object[] или любой другой супертип, применяемый в вашем случае:

return new Object[0];

и

return list.toArray();

(требуются непроверенные приведения, но это должно быть нормально)

Редактировать:

Хорошо, и что <K extends Comparable> ?
В этом случае используйте:

return new Comparable[0];

и

return (Comparable[])list.toArray(new Comparable[]);

Комментарии:

1. Я думал об этом, но это не так просто. Метод не может вернуть объект, он должен вернуть сопоставимый.

2. Сам массив никогда не сопоставим, содержащиеся в нем значения могут быть. И в вашем случае они сопоставимы, потому что вы помещаете целочисленные объекты в массив. Вы пробовали мой подход? — Как я пытался объяснить: вы можете, конечно, использовать new Integer[0]; или все, что соответствует ожидаемому (супер-) типу.

3. Я пробовал, но безрезультатно. Если он возвращает объект, он выдает ClassCastException, потому что класс сравнивает ключи, чтобы узнать, куда вставить новый узел, поэтому он должен быть классом, который реализует сопоставимый интерфейс. Делая это по-моему, он не пройдет тест, потому что, когда корень равен нулю, он возвращает нулевой массив, а не массив класса элементов, как запрашивает тест. Помните, что я не могу изменить возврат метода, ни параметр, ни тест. Я только надеялся, что есть какой-то способ сообщить коду, что я хочу, чтобы это был не нулевой массив, а пустой массив любого класса ключей дерева.