Подтвердить что ты не робот

Структура данных обслуживания заказа в С++

Я ищу структуру данных, которая бы эффективно разрешала проблему обслуживания заказа. Другими словами, мне нужно эффективно

  • вставить (посередине),
  • удалить (посередине),
  • сравнивает позиции элементов в контейнере.

Я нашел хорошие статьи, которые обсуждают эту проблему:

Алгоритмы довольно эффективны (какое-то состояние должно быть O (1) для всех операций), но они не кажутся тривиальными, и мне интересно, есть ли реализация С++ с открытым исходным кодом этих или подобных структур данных,

Я видел связанную тему, были предложены более простые подходы с временной сложностью O (log n) для всех операций, но здесь я ищу существующую реализацию.

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

Подробнее

Я собираюсь

  • сохранить список указателей на объекты,
  • время от времени мне нужно будет изменить порядок объектов (удалить + вставить),
  • для подмножества объектов мне нужно иметь возможность быстро сортировать их и обрабатывать их в правильном порядке.

Примечание

Стандартные контейнеры для упорядочения (std:: set, std:: map) - это не то, что я ищу, потому что они будут поддерживать порядок для меня, но мне нужно самостоятельно заказать элементы. Подобно тому, что я сделал бы с std:: list, но сравнение позиций было бы линейным, что неприемлемо.

4b9b3361

Ответ 1

Если вы ищете простое в использовании и эффективное решение, вы можете построить эту структуру, используя сбалансированное двоичное дерево поиска (AVL или дерево Red-Black). Вы можете выполнить следующие операции:

  • вставить (X, Y) (вставляет X сразу после Y в общем порядке) - если X > не имеет права дочернего, установите правильный дочерний элемент X как Y, иначе пусть Z будет самым левым node дерева с корнем X.right (это означает, что самый низкий Z = X.right.left.left.left..., который не является NULL) и установите его дочернее значение Z Y. Баланс, если вам нужно. Вы можете видеть, что общая сложность будет равна O (log n).
  • удалить (X) - просто удалите node X, как обычно, из дерева. Сложность O (log n).
  • сравнить (X, Y) - найти путь от X к корню и путь от Y к корню. Вы можете найти Z, самый низкий общий предок X и Y, из этих двух путей. Теперь вы можете сравнить X и Y в зависимости от того, находятся ли они в левом или в правом поддереве Z (они не могут быть в том же поддереве одновременно с тех пор Z не будет их самым низким общим предком). Сложность O (log n).

Итак, вы можете видеть, что преимущество этой реализации состоит в том, что все операции будут иметь сложность O (log n) и ее легко реализовать.

Ответ 2

Вы можете использовать список пропусков, аналогичный тому, как вы используете std:: list

Списки пропусков были впервые описаны в 1989 году Уильямом Пью. Процитировать автора:

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

http://drum.lib.umd.edu/handle/1903/542

Ответ 3

STL - это решение вашей проблемы.
Это стандартные, проверенные и эффективные контейнеры и алгоритмы, которые их поддерживают. почти все контейнеры в STL поддерживают упомянутые вами действия.

Кажется, что std::deque имеет лучшие качества для задач, которые вы имеете в виду:
1) Вставка: как сзади, так и спереди в сложности O (1)
2) Удаление: в отличие от непрерывных контейнеров, std::deque::erase - O (N), где N - количество удаленных элементов. что стирание только одного элемента имеет сложность O (1)
3) Сравнение позиций: используя std::advance, сложность на std::deque равна O (N)
4) Сортировка: используя std::sort, обычно будет использовать быструю сортировку для задачи и будет работать в O (n * log n). В MSVС++, по крайней мере, функция пытается угадать, что является лучшим алгоритмом сортировки для данного контейнера.

не пытайтесь использовать решение с открытым исходным кодом/создайте свою собственную библиотеку, прежде чем пытаться использовать STL!