Какова структура данных Zipper и должен ли я ее использовать?
вопрос прост: я не могу понять молнии структуры данных.
мой вопрос связан с его использованием с деревом.
Я хочу понять, как я могу изменить узле дерева с помощью молнии. И как не копировать все дерево (или большую его часть).
пожалуйста, уточните, если я ошибаюсь с застежкой-молнией. Может быть, это не может помочь с обновлением дерева?
Или, может быть, можно обновить дерево и я просто не вижу способ?
4 ответов
давайте начнем с Zipper-analog для списков. Если вы хотите изменить N-й элемент списка, он принимает O(n), потому что вам нужно скопировать N-1 первых элементов. Вместо этого вы можете сохранить список как структуру ((первые N-1 элементов перевернуты) N-й элемент (остальные элементы)). Например, список (1 2 3 4 5 6)
изменяемый в 3 будет представлен как ((2 1) 3 (4 5 6))
. Теперь, вы можете легко изменить 3 на что-то другое. Вы также можете легко переместить фокус влево ((1) 2 (3 4 5 6))
и справа ((3 2 1) 4 (5 6))
.
молния-это та же идея, что и для деревьев. Вы представляете определенный фокус в дереве плюс контекст (до родителей, до детей), который дает вам все дерево в форме, где оно легко модифицируется в фокусе, и легко перемещать фокус вверх и вниз.
вот очень хорошая статья, объясняющая использование молнии для диспетчера окон плитки в Haskell. Статья в Википедии не является хорошей ссылкой.
короче говоря, молния является указателем или ручкой на определенный узел в структуре дерева или списка. Молния дает естественный способ взять древовидную структуру и относиться к ней так, как будто дерево было "поднято" сфокусированным узлом - по сути, вы получаете второе дерево, не требуя дополнительных копий оригинальное дерево или влияет на других пользователей дерева.
в приведенном примере показано, как окна первоначально отсортированы по местоположению на экране, а затем для моделирования фокуса вы используете молнию, направленную на окно фокуса. Вы получаете хороший набор операций O(1), таких как вставка и удаление, без необходимости особого случая окна фокусировки или написания дополнительного кода.
в этой статье связано с Haskell, но это также объясняет молнии довольно хорошо, и это должно быть легко абстрагироваться от Haskell-специфики.