Как многократно вставлять элементы в отсортированный список быстро - PullRequest
3 голосов
/ 09 ноября 2011

У меня нет официального обучения CS, поэтому терпите меня.

Мне нужно сделать симуляцию, которая может абстрагироваться от следующего (опуская детали):

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

  1. удалить первое событие и
  2. в результате "обработки" несколько других событий могут быть вставлены в список в более позднее время

и повторите это много раз.

Вопросы

Какую структуру данных / алгоритм я могу использовать для максимально эффективной реализации этого? Мне нужно значительно увеличить количество событий / номеров в списке. Приоритет - сделать это как можно быстрее для длинного списка.

Так как я делаю это в C ++, какие структуры данных уже доступны в STL или бусте, которые облегчат реализацию этого?


Подробнее:

Количество событий в списке является переменным, но оно гарантированно будет между n и 2*n, где n - некоторый параметр моделирования. В то время как время событий увеличивается, разница во времени самых последних и самых ранних событий также гарантированно будет меньше постоянной T. Наконец, я подозреваю, что плотность событий во времени, хотя и не является постоянной, также имеет верхнюю и нижнюю границу (то есть все события никогда не будут сильно сгруппированы вокруг одного момента времени)

Усилия на данный момент:

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

Прямо сейчас я использую приближение, в котором я делю время на сегменты и отслеживаю, сколько событий в каждом сегменте. Затем обрабатывайте сегменты один за другим по мере того, как «проходит» время, всегда добавляя новый сегмент в конце при удалении одного из фронта, таким образом сохраняя количество блоков постоянным. Это быстро, но только приблизительное.

Ответы [ 4 ]

5 голосов
/ 09 ноября 2011

Мин-куча может удовлетворить ваши потребности. Здесь есть объяснение , и я думаю, что STL предоставит вам priority_queue.

Время вставки O (журнал N), удаление O (журнал N)

4 голосов
/ 09 ноября 2011

Звучит так, как будто вам нужна / нужна приоритетная очередь.Если память служит, адаптер очереди приоритетов в стандартной библиотеке записывается для извлечения самых больших элементов, а не самых маленьких, поэтому вам нужно будет указать, что для сравнения он использует std::greater.

Кроме этого,он обеспечивает примерно то, что вы просили: возможность быстрого доступа / удаления самого маленького / самого большого элемента и возможность быстрого добавления новых элементов.Хотя он не поддерживает все элементы в порядке, он поддерживает достаточный порядок, чтобы по-прежнему быстро находить / удалять самый маленький (или самый большой) элемент.

2 голосов
/ 09 ноября 2011

Я бы начал с очереди с базовым приоритетом и посмотрел, достаточно ли это быстро. Если нет, то вы можете написать что-нибудь нестандартное.

http://en.wikipedia.org/wiki/Priority_queue

1 голос
/ 09 ноября 2011

Бинарное дерево всегда сортируется и имеет более быстрое время доступа, чем линейный список. Время поиска, вставки и удаления равно O (log (n)).

Но это зависит от того, нужно ли сортировать предметы постоянно или только после завершения процесса. В последнем случае хеш-таблица, вероятно, быстрее. В конце процесса вы должны скопировать элементы в массив или список и отсортировать их.

...