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


11

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

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

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

Ответы:


13

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

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

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


Спасибо. Похоже, 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) на уровне листьев.


Ссылки перерыва; пожалуйста, дайте правильную, надежную ссылку (которая позволяет людям найти ваш документ без ссылки).
Рафаэль

Я не опубликовал статью в журнале любого, только на моем личном сайте. Если , вероятно , положил его на Arxiv , хотя, хорошая идея.
jkff

Я в основном думал об авторе (ах), названии и году - это облегчает поиск в Google, если это необходимо. Поместить его на arXiv было бы еще лучше, правда!
Рафаэль
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.