2010-12-30 2 views
17

Кто-нибудь знает структуру данных, которая эффективно поддерживает две операции?Структура данных для выбора случайных элементов?

  1. Вставить значение в структуру данных.
  2. Отменить и вернуть запись из структуры данных с равномерно случайной вероятностью.

Это похоже на канонический «мешок из мрамора», который всегда появляется во вводных классах вероятности. Вы можете помещать произвольные мраморы в сумку и затем эффективно удалять мрамор в случайном порядке.

Лучшее решение, которое у меня есть, - использовать самобалансирующееся двоичное дерево поиска (AVL, AA, red/black и т. Д.) Для хранения элементов. Это дает время вставки O (lg n). Чтобы удалить случайный элемент, выберите случайный индекс i, затем найдите и удалите i-й элемент из дерева. Если вы соответствующим образом внедрили структуру, это можно сделать и в O (lg n).

Это время исполнения, конечно, неплохо, но мне любопытно, возможно ли сделать лучше - возможно, O (1) для вставки и O (lg n) для детекций? Или, возможно, что-то, что работает в ожидается O (1) вставить и удалить с помощью хеш-функций? Или, возможно, более сильная амортизация?

Есть ли у кого-нибудь идеи, как сделать это асимптотически быстрее?

+0

Просто из любопытства: кто-нибудь знает, имеет ли эта структура данных имя? Это, очевидно, тип 'Bag' и/или' MultiSet'. «RandomBag», может быть? На самом деле, каковы такие структуры данных (т. Е. Структуры данных, в которых 'pop' возвращает и удаляет случайный элемент), который называется * вообще *? –

+0

Я слышал, что здесь используются слова «Сумка» и «RandomBag», но я думаю, что RandomBag, вероятно, правильный термин; Сумка обычно является синонимом мультимножества. – templatetypedef

ответ

35

Да. Используйте вектор.

Чтобы вставить, просто поместите в конец и увеличьте размер. Чтобы удалить, выберите элемент произвольно, поменяйте его содержимое конечным значением, затем выскочите конечное значение (т. Е. Верните конечное значение и уменьшите размер вектора).

Обе операции амортизируются O (1).

+5

Когда вам не нужно сохранять порядок, структуры данных настолько просты :) –

+1

Beautiful! Это фантастическое решение. Спасибо! – templatetypedef

+3

@templatetypedef: Мое удовольствие. :-) Кстати, если вы обращаетесь в Google, вы должны знать, что этот метод в основном является вариантом Shisher. За исключением того, что вместо того, чтобы оставлять перетасованные значения в массиве, вы извлекаете их все. :-П –

Смежные вопросы