Эффективно найти средний элемент в set'е

227
20 ноября 2017, 20:13

std::set обычно представлен бинарным деревом поиска. У него есть методы begin и end, которые позволяют получить минимум и максимум, а также lower_bound и upper_bound для бинарного поиска. А что если мне надо получить итератор, указывающий на элемент в середине сета (или один из них, если в нём чётное число элементов)?

Есть ли эффективный способ сделать это (за O(lb(size)) вместо O(size))?

{1} => 1
{1,2} => 1 или 2
{1,2,3} => 2
{1,2,3,4} => 2 или 3 (но в ту же сторону от середины, что и с {1,2})
{1,312,10000,14000,152333} => 10000

PS: Этот вопрос на английском.

Answer 1

Или, если все-таки использовать set, то можно поддерживать итератор, указывающий на медианный элемент и число элементов k до этого итератора.

  • Изначально set пустой, итератор равен set.end(), k равно нулю
  • При добавлении элемента в set:
    • новый элемент больше медианного => при необходимости (если k * 2 + 3 <= set.size()) сдвигааем итератор на один вперед и увеличиваем k на единицу.
    • новый элемент меньше медианного => при необходимости сдвигааем итератор на один назад и уменьшаем k на единицу.
  • При удалении элемента из set действуем аналогично, при необходимости двигаем итератор на единицу вперед/назад
  • Таким образом, в любой момент времени у нас есть итератор на медианный элемент, дополнительные расходы для поддержания этого итератора составляют O(log n) на каждую операцию вставки/удаления

И еще вот полезный вопрос на английском Stack Overflow примерно про это же (там без удаления, но идея такая же)

Answer 2

Если писать свое декартово дерево не хочется, то можно использовать встроенную в gcc структуру данных rope

Answer 3

Думаю, что нет. Ну смотрите, для поиска минимума в BST нужно всегда идти в левую ветку, максимума - в правую. И вот хотите Вы найти средний. И с самого начала неизвестно, что делать. Условно, у вас в корне дерева стоит "10", больше Вы ничего не знаете о содержимом. Куда пойдете?

READ ALSO
Изменение цены с помощью jquery

Изменение цены с помощью jquery

Пытаюсь сделать следующее: при нажатии на input, его value должно прибавляться к value другого input'а, тем самым увеличивая ценуПытался так но не прибавляется

270
Закрыть блок по клику на область

Закрыть блок по клику на область

Есть кнопка, по клику вылазит корзинаПодскажите, как закрыть корзину по клику на любую область экрана за пределами корзины ? Сейчас корзина...

239
Rtl slick slider

Rtl slick slider

Ребят помогите советомЕсть два slick слайдера

244