Вычислительная сложность операций TreeSet в Java?

Я пытаюсь прояснить некоторые вещи, касающиеся сложности некоторых операций TreeSet. В javadoc говорится:

«Эта реализация обеспечивает гарантированные временные затраты журнала (n) для основных операций (добавления, удаления и содержания)».

Все идет нормально. Мой вопрос в том, что происходит с addAll (), removeAll () и т. Д. Здесь javadoc для Set говорит:

«Если указанная коллекция также является набором, операция addAll эффективно изменяет этот набор, так что его значение является объединением двух наборов».

Это просто объяснение логического результата операции или намек на ее сложность? Я имею в виду, если два набора представлены, например, красно-черным деревьям лучше было бы как-то соединять деревья, чем «складывать» каждый элемент одного к другому.

В любом случае, есть ли способ объединить два TreeSet в один со сложностью O (logn)?

Заранее спасибо. :-)


person Andreas K.    schedule 02.08.2010    source источник
comment
Отвечая на полученные ответы: я не совсем понимаю этого. Предположим, у вас есть два SortedSet, которые не имеют перекрывающихся элементов и представлены красно-черными деревьями. Почему вы не можете присоединиться к ним, поскольку операция соединения в красно-черных деревьях занимает O (log (n + m)) времени?   -  person Andreas K.    schedule 02.08.2010


Ответы (4)


Вы можете себе представить, как можно было бы оптимизировать специальные случаи до O(log n), но в худшем случае должно быть O(m log n), где m и n - количество элементов в каждом дереве.

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

http://net.pku.edu.cn/~course/cs101/resource/Intro2Algorithm/book6/chap14.htm

Описывает алгоритм особого случая, который может объединять деревья в O(log(m + n)), но обратите внимание на ограничение: все элементы S1 должны быть меньше, чем все элементы S2. Я имел в виду, что есть специальные оптимизации для особых случаев.

person bshields    schedule 02.08.2010
comment
вот ссылка: oreilly.com/library/view / data-structure-and / 9788131755679 / - person msangel; 10.04.2019
comment
Ссылка возвращает 403. - person Ed J; 06.05.2020

Глядя на исходный код Java для TreeSet, похоже, что если переданная коллекция является SortedSet, тогда он использует алгоритм времени O (n). В противном случае он вызывает super.addAll, что, как я предполагаю, приведет к O (n logn).

РЕДАКТИРОВАТЬ - думаю, я слишком быстро прочитал код, TreeSet может использовать алгоритм O (n) только в том случае, если его резервная карта пуста

person Kiersten Arnold    schedule 02.08.2010

Согласно этому сообщению в блоге:
http://rgrig.blogspot.com/2008/06/java-api-complexity-guarantees.html
это O (n log n). Поскольку документация не дает намеков на сложность, вы можете написать свой собственный алгоритм, если производительность для вас критична.

person Karel Petranek    schedule 02.08.2010

Невозможно выполнить слияние деревьев или наборов соединений, как в структурах данных с несвязанными наборами, потому что вы не знаете, являются ли элементы в двух деревьях непересекающимися. Поскольку структуры данных имеют сведения о содержимом в других деревьях, необходимо проверить, существует ли один элемент в другом дереве, прежде чем добавлять к нему или, по крайней мере, пытаться добавить его в другое дерево и отменить добавление, если вы найдете его на путь. Значит, должно быть O (MlogN)

person user855    schedule 02.08.2010
comment
Я не могу этого понять. Предположим, у вас есть два SortedSet, которые не имеют перекрывающихся элементов и представлены красно-черными деревьями. Почему вы не можете присоединиться к ним, поскольку операция соединения в красно-черных деревьях занимает O (log (n + m)) времени? - person Andreas K.; 02.08.2010
comment
Учитывая 2 произвольных TreeSet, как вы узнаете, так ли это? - person user855; 02.08.2010
comment
Что ж, согласно программе, которую я сейчас создаю, я могу гарантировать, что два TreeSet не будут иметь перекрывающихся элементов. Однако кажется, что я не могу присоединиться к ним в O (log (n + m)), как указано в остальных ответах ... - person Andreas K.; 02.08.2010