Реализация неизменяемой (постоянной) структуры данных в виде массива с быстрой индексацией, добавлением, предварительным добавлением, итерацией

11

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

Clojure обеспечивает постоянный вектор, но это только для быстрого добавления. Вектор Scala эффективно добавляет и добавляет в постоянное время, но я не могу понять, как он реализован, поскольку он основан на той же структуре данных (векторное преобразование с растровым отображением), что и вектор Clojure, и, как я понимаю, на основе векторного преобразования с побитовым отображением не может быстро подготовиться без некоторых уловок.

Меня интересует не готовая к использованию реализация, а описание того, как реализовать такую ​​структуру данных самостоятельно.

Tvaroh
источник

Ответы:

13

Очевидным кандидатом является постоянное сбалансированное двоичное дерево. Все перечисленные вами операции можно выполнить за или , используя копирование пути . Для получения более подробной информации о том, как добиться этого времени выполнения, см. Книгу Криса Окасаки, на которую ссылаются ниже, или мой ответ здесь .O ( LG N )O(1)O(lgn)

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

Стандартным справочником является книга Криса Окасаки 1998 года "Чисто функциональные структуры данных".
Смотрите также

DW
источник
Спасибо. Похоже, RRB-деревья - хороший кандидат, и они уже имеют (не полную) реализацию Clojure.
Тварох
Я думаю, что Окасаки говорит нам, как достичь этих времен выполнения при неизменности и постоянстве?
Рафаэль
1
@ Рафаэль, ага. Я добавил ссылки, чтобы объяснить, как вы достигаете времени выполнения (к началу моего ответа).
DW
4

Я описал одну реализацию такой структуры данных в моей статье о добавочном сопоставлении регулярных выражений - см. Http://jkff.info/articles/ire/#ropes-strings-with-fast-concatenation и текст ниже и выше этого раздела. ,

Это разновидность дерева постоянной высоты (например, B-деревья или 2-3 дерева). По сути, это (2,3) дерево, листья которого являются (N, 2N-1) массивами, чтобы избежать накладных расходов на элемент. (Массив (N, 2N-1) - это массив, длина которого находится в диапазоне N..2N-1.) Чем больше N, тем меньше накладные расходы, но линейно увеличивается сложность разбиения и объединения. Такие операции, как индексация, разбиение и конкатенация, очень похожи на то, как они работают в 2-3 деревьях, обобщая (N, 2N-1) на уровне листьев.

jkff
источник
Ссылки перерыва; пожалуйста, дайте правильную, надежную ссылку (которая позволяет людям найти ваш документ без ссылки).
Рафаэль
Я не опубликовал статью в журнале любого, только на моем личном сайте. Если , вероятно , положил его на Arxiv , хотя, хорошая идея.
jkff
Я в основном думал об авторе (ах), названии и году - это облегчает поиск в Google, если это необходимо. Поместить его на arXiv было бы еще лучше, правда!
Рафаэль