Для домашнего задания мне нужно понять, как работает список пропусков .
Я программирую чуть более 2 лет (я знаю, что это не так уж долго на самом деле), и я никогда даже не слышал о пропущенном списке.
Я просмотрел все руководства, которые смог найти, и до сих пор едва понимаю, как они работают. Я даже искал Code Review для примера реализации и нашел только один обзор; и это даже не полная реализация. Я просмотрел пример реализации, предоставленной курсом, и он абсолютно ужасен. Между отсутствием правильных методов и однобуквенными именами переменных я понятия не имею, как это работает.
Как работает список пропусков? Требуется ли знание списка пропусков для понимания более сложных структур данных?
data-structures
Carcigenicate
источник
источник
Ответы:
В былые времена в классе структур данных мы узнали, как работают деревья AVL . У меня было бы это на одном из моих занятий, но преподаватель сказал: «Вы никогда не будете использовать это на самом деле», и вместо этого попросил нас выучить 2-3 дерева и б * деревья. Это были дни, когда память была тесной и процессы были однопоточными. Вы не использовали deque, когда одинаково связанный список будет работать так же хорошо.
Список пропусков сегодня встречается гораздо чаще, поскольку проблема заключается в большей доступной памяти и параллелизме (вам не нужно вообще блокировать, когда вы выполняете роль писателя в списке пропусков - по сравнению со всем, что имеет дерево AVL).
Честно говоря, сейчас это моя любимая структура данных, и я легко могу рассуждать о том, как она работает, и где она будет выгодна или невыгодна для использования.
Вам не нужно будет писать его с нуля (если только вы не получите его в качестве вопроса для интервью - но тогда вы с такой же вероятностью сможете реализовать дерево AVL).
Вы будете нуждаться , чтобы понять , почему вы хотите , чтобы выбрать
ConcurrentSkipListMap
в Java , а неHashMap
или ,TreeMap
или любой из других реализаций карты.Чтобы понять, как это работает, вам нужно понять, как работает двоичное дерево. Подождите, позвольте мне изменить это. Вы должны понимать, как работает сбалансированное двоичное дерево. Без балансировки двоичного дерева вы не получите никакого реального преимущества с его поиском.
Допустим, у нас есть это дерево:
И мы вставляем в него «8». Теперь у нас есть:
И это не сбалансировано. Итак, мы идем и делаем волшебство балансировки через некоторую реализацию ...
И у тебя снова сбалансированное дерево. Но это было много магии, я махнул рукой.
Давайте возьмем список пропуска.
Это один идеализированный. Немного, но это показывает сбалансированную двоичную древовидную природу, которую аппроксимирует идеал пропуска.
Теперь мы хотим вставить туда 6. Это вставляет его так же, как связанный список. Однако мы начинаем сверху и спускаемся. Верхняя точка указывает на 5. Является ли 6> 5? Да. Хорошо, теперь вершина заканчивается до конца, поэтому мы идем вниз по стеку (мы находимся на 5). Следующим является 7. Является ли 6> 7? Нет. Итак, мы идем вниз по уровню и находимся на базовом уровне, поэтому мы вставляем 6 справа от 5.
Мы подбрасываем монету - головы строим, хвосты остаемся. Хвосты. Больше ничего не нужно делать.
Давайте вставим это 8 сейчас. 8> 5? Ага. 8> 7? Ага. И теперь мы снова на нижнем уровне после следующих стрелок и стека и тестируем 8> 11? Нет. Таким образом, мы вставляем 8 справа от 7.
Мы подбрасываем монету - головы строим, хвосты остаемся. Хвосты. Больше ничего не нужно делать.
В сбалансированном дереве мы бы все расстроились из-за того, что дерево сейчас не сбалансировано. Но это не дерево - это список пропусков. Мы приближаем сбалансированное дерево.
Теперь давайте вставим 10. Я буду избегать всех сравнений.
Мы подбрасываем монету - головы строим, хвосты остаемся. Heads! И снова переверни, Головы снова! Переверните это снова, хорошо, есть хвосты. Два уровня выше базового связного списка.
Преимущество здесь в том, что теперь, если мы собираемся вставить 12, мы можем пропустить от 5 до 10, не делая все эти другие сравнения. Мы можем пропустить их с помощью списка пропусков. И нам не нужно беспокоиться о сбалансированном дереве - вероятностный характер суммирования делает это для нас.
Почему это так полезно? Потому что, вставляя 10, я могу сделать это, блокируя запись на 5 и 7 и 8 указателях, а не на всю структуру. И пока я делаю это, читатели могут просматривать список пропусков, не имея противоречивого состояния. Для одновременного использования быстрее не нужно блокировать. Для итерации по нижнему слою, это быстрее, чем дерево (радости алгоритмов BFS и DFS для навигации по дереву - вам не нужно беспокоиться о них).
Вы столкнетесь с этим? Вы, вероятно, увидите его в использовании в некоторых местах. И тогда вы поймете, почему автор выбрал эту реализацию, а не
TreeMap
илиHashMap
для структуры.Многое из этого было позаимствовано из моего поста в блоге: The Skip List
источник