Всем привет!
Недавно на хабрахабре была опубликована статья про такую структуру данных, как списки с пропусками. Как мне показалось, структура весьма интересна и при этом проста в использовании. Именно поэтому сейчас я решил поэкспериментировать со структурой на различных задачах и попробовать реализовать над ней различные модификации. "Базовые" операции достаточно хорошо описаны в статье с хабрахабра, а также в статье с вики-конспектов ИТМО. Поэтому я не буду на них останавливаться и сразу перейду к более интересным.
Базовая реализация.
Здесь "чистый" вариант списков с пропусками — реализованы самые базовые операции — поиск, вставка, удаление.
Добавляем работу с порядковыми статистиками.
Теперь нам понадобятся функции find_by_order()
и order_of_key()
. Для того, чтобы использовать их в сбалансированных деревьях, мы поддерживали размеры поддеревьев. Здесь же прийдётся дополнительно поддерживать длины ссылок. После этого обе функции реализуются очень легко. Для первой мы заменяем в условии проверку значений на проверку текущей длины от начала, то есть, на проверку порядкового номера. Во второй же функции мы делаем всё аналогично обычному find()
, но при этом записываем в отдельную переменную длину пройденного пути.
Делаем структуру по неявному ключу.
Фактически, добавив операцию find_by_order()
из предыдущего пункта мы уже получили все возможности для того, чтобы производить операции по неявному ключу. Всё, что нужно для этого — вместо функции find()
при вставке использовать функцию find_by_order()
. Для удобства можно перегрузить оператор [].
Вообще, я ещё планировал написать rope (возможность вырезать/вставлять отрезки) и, может быть, модификации на подотрезках, но после того, как структура не справилась с довольно простыми задачами по лимиту времени, моё рвение поуменьшилось :) В любом случае опубликую то, что уже было сделано, может, кому-то ещё будет интересно или полезно.
P.S. А что вы думаете об этой структуре? Есть ли среди посетителей codeforces те, кто ей пользуется? Насколько разумно использовать списки с пропусками на контестах? Какие ещё могут быть сделаны полезные модификации структуры? И да, моя реализация необычайно медленна и местами вмещает слишком много кода. Может, кто-нибудь знает варианты получше?
Я может туплю спросонок, но если речь про SkipList-ы то они в джаве "из коробки" присутствуют: ConcurrentSkipListMap
Основной смысл в том что если в качестве конкурентной замены
HashMap
юзается ConcurrentHashMap то вотTreeMap
(как реализацияNavigableMap
) заменяется именно вышеупомянутой структурой.Не знаю могли ли разработчики выкрутиться иначе и выдумать конкуррентную версию красно-чёрного дерева — мне так сразу на ум не приходит :)
Ну соответственно ConcurrentSkipListMap source если найдётся на него терпение :)
могли нагуглить статьи по теме. Вот например — красно-черное дерево wait-free (0_0)
Столько текста сразу я не выкурю, да и наверное не очень прямо сейчас нужно. Но вы правы, гугл подсказывает что эксперименты разные группы исследователей над деревом проделывали и проделывают...
А что касается авторов джаванской реализации — если я правильно понимаю эта работа в частности появилась несколько позже (2012?) чем ConcurrentSkipListMap (2006?) в джаве :)
блин...в название поста в первом слове не прочитал букву "П"...
#интеллектуальный_юмор
Схожесть аватарок IDont_love_TanyaRomanova и adamant является вымышленной.
Совпадение цветов аватарок с цветами участников является случайным.
(сорри за оффтопик)
окей, я понимаю что, может быть, мой коммент был немного пошловат, но все, при чем здесь моя авка и авка adamant?
Мой коммент не имеет никакой смысловой связи с темой, просто глупый юмор.
Как и ваш. :D
It was very interested with me too. But now, it is not. I realized it's a weak data structure. I can't upgrade it for more advanced features. Now I used to use AVL or Splay tree, they are more powerful, they can support operators in segment trees (e.g. lazy update).
P/S: This is my implementation for "auto-balanced dynamic-allocation segment tree" (Segment tree + AVL) http://codeforces.me/blog/entry/12285