Создание общего дерева бинарного поиска

public double sum(TreeNode root){
    Queue<TreeNode> queue = new ArrayDeque<>();
    double sum = 0;
    if (root!=null){
        queue.add(root);
    }
    while(!queue.isEmpty()){
        int size = queue.size();
        for (int i = 0; i < size; i++) {
            TreeNode current = queue.remove();
            sum += current.value;
            if (current.leftChild!=null)
                queue.add(current.leftChild);
            if (current.rightChild!=null)
                queue.add(current.rightChild);
        }
    }
    return sum;
}

Теперь мне нужно реализовать общее двоичное дерево поиска, которое может хранить в поле value узла либо Character, либо Integer, либо Double (если Character является общим параметром дерева, то его кодовая сумма ASCII будет возвращена из sum() метод).

И мне нужно выполнять различные операции, такие как sum() всех значений узла (также вставлять, удалять, искать, максимальное, минимальное и т. д.).

Но я застрял на том, чтобы сделать мою реализацию универсальной. В методе sum() выдает ошибку в строке

sum += current.value;

Оператор + не может быть применен к T.

Как я могу решить эту проблему?

На самом деле атрибут/свойство value класса TreeNode является общим.

shubham berlia 18.12.2022 19:27

Не могли бы вы добавить сюда остальные ваши коды?

Shavarsh Shahoyan 18.12.2022 20:02
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
83
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Арифметические операторы нельзя использовать с произвольным типом, они применимы только к числовым примитивам и их типам-оболочкам. Поэтому, если вам нужно обобщить свою логику, это не тот путь.

Вместо этого вы можете определить поле типа BiFunction, которое представляет собой функцию, ожидающую два аргумента, на уровне вашего Tree класса (или любого другого его имени). И используйте это BinaryOperator для накопления значений узлов при обходе дерева.

На основании этой цитаты:

если Character является общим параметром Дерева, то его кодовая сумма ASCII будет возвращена из метода sum()

Я предполагаю, что вам нужно сохранить тип возвращаемого значения метода sum() как double. Поскольку в соответствии с требованиями вашего задания необходимо поддерживать только три универсальных типа: Character, Integer или Double, это выполнимо.

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

BiFunction<Double, Double, Double> intMerger = Double::sum;
BiFunction<Integer, Double, Double> intMerger = (i, d) -> i + d;
BiFunction<Character, Double, Double> intMerger = (c, d) -> c + d;

Кроме того, поскольку вам нужно выполнять такие операции, как бинарный поиск в вашем универсальном дереве, вам нужно либо определить общий параметр T как расширяющий Comparable интерфейс, либо предоставить Comparator (в противном случае вы не сможете определить, какое значение больше/меньше при реализации бинарный поиск или поиск минимального/максимального значения). Поскольку все типы, которые должны поддерживаться, сопоставимы, вы можете использовать первый вариант и определить параметр Generic как T extends Comparable<T>, что на простом английском языке означает: что-то, что умеет сравнивать себя.

В результате у вас может получиться что-то вроде этого:

public class MyTree<T extends Comparable<T>> {
    private final BiFunction<T, Double, Double> merger;

    public MyTree(BiFunction<T, Double, Double> merger) {
        this.merger = merger;
    }

    public double sum(TreeNode<T> root) {
        double total = 0;
        if (root == null) return total;
        
        Queue<TreeNode<T>> queue = new ArrayDeque<>();
        queue.add(root);
        
        while (!queue.isEmpty()) {
            int size = queue.size();
            TreeNode<T> current = queue.remove();

            total = merger.apply(current.value, total);
            
            if (current.leftChild != null) queue.add(current.leftChild);
            if (current.rightChild != null) queue.add(current.rightChild);
        }
        return total;
    }
    
    private static class TreeNode<T extends Comparable<T>> {
        private T value;
        private TreeNode<T> leftChild;
        private TreeNode<T> rightChild;
        
        // constructor, etc.
    }
}

Пример использования:

MyTree<Double> myTree1 = new MyTree<>(Double::sum);
MyTree<Integer> myTree2 = new MyTree<>((i, d) -> i + d);
MyTree<Character> myTree3 = new MyTree<>((c, d) -> c + d);

Примечание: если то, что я говорил о введении функции, кажется вам чуждым, взгляните на этот учебник, предоставленный Oracle.

Другие вопросы по теме

Похожие вопросы

MySQL: 8.0.31 — большие пробелы (тысячи) в поле идентификатора после нескольких месяцев использования
Как исправить исключение в потоке «main» java.lang.Error: нерешенная проблема компиляции: синтаксическая ошибка, вставьте «}», чтобы завершить ошибку ClassBody?
Преобразование для каждого цикла в поток
Файлы не удаляются в Android 11 с помощью MediaStore.createDeleteRequest()
Вопрос для интервью. Структура данных, выполняющая операцию CRUD за время O (1) и поддерживающая порядок вставки
Как заставить SpringBoot найти мой файл в каталоге src/main/resources
Java/ASM: индекс 0 выходит за пределы длины 0, хотя список имеет длину 1024 элемента
Как я могу суммировать числа, которые находятся рядом друг с другом в списке, и добавить эту сумму в тот же список между числами, которые я суммирую?
Gradle сгенерировал неподдерживаемый файл класса основной версии 63
Почему в этом коде студия Android выделена желтым цветом?