Як працює пропускний список?


14

Для виконання домашнього завдання мені потрібно зрозуміти, як працює пропускний список .

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

Я переглянув усі посібники, які можу знайти, і досі лише ледве розумію, як вони працюють. Я навіть шукав Code Review для прикладу реалізації, і знайшов лише один огляд; і це навіть не повна реалізація. Я переглянув зразок реалізації, наданий курсом, і це абсолютно жорстоко. Між відсутністю належних методів та однолітерними назвами змінних, я не маю поняття, як це працює.

Як працює пропускний список? Чи потрібне знання пропускного списку для розуміння більш досконалих структур даних?



1
Поради щодо освіти явно поза темою . Оскільки це стосується структури даних, а не освіти, я відредагував ваше запитання, щоб видалити ці частини. Я також рекомендую прочитати посилання на Вікіпедію, до якого я відредагував, і оновити ваше питання з більш конкретними подробицями про те, що ви досі не розумієте.

@Snowman Дякую Я лише додав, що для запобігання коментарям типу "запитайте свого вчителя". Я буду мати це на увазі наступного разу. І ви додали редагування, яке змінює питання. Зрештою, я не прошу людей пояснювати, як вони працюють, оскільки я припускаю, що це офтопік (хоча я б не проти хорошого пояснення). Я просто хочу знати, наскільки вони важливі для навчання.
Carcigenicate

1
@Carcigenicate пояснюючи, як вони працюють, насправді більше стосується теми, ніж запитує, чи побачите ви їх у реальному світі. Ми можемо лише здогадуватися, що ти будеш робити та різні царства. На запитання, чи бачимо ми їх у реальному світі, опитуємо нас на "так, я бачу їх і використовую" або "ні, ніколи про це не чути" - що не дає хороших чи корисних відповідей для читання іншими людьми.

Відповіді:


29

За старих часів у класі структур даних ми дізналися, як працюють дерева AVL . Я б мав це в одному з моїх занять, але викладач сказав: "Ви ніколи цього не використовуєте", а натомість навчив нас 2-3 дерева та b * дерева. Це були дні, коли пам’ять була тісною і процеси були окремо нарізані. Ви не використовували декес, коли спільно пов'язаний список працював би так само добре.

Сьогодні список пропусків набагато частіше зустрічається, тому що більше доступної пам’яті та одночасності є проблемою (вам взагалі не потрібно дуже сильно фіксувати, коли ви виступаєте як автор у списку пропусків - порівняно з усім із деревом 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. Я уникаю всіх порівнянь.

Ми гортаємо монету - голови ми будуємо, хвости залишаємося. Голови! І переверніть його знову, голови! Переверніть знову, добре, там є хвости. Два рівні над базовим пов'язаним списком.

пропустити список після ще однієї вставки

Перевага тут полягає в тому, що зараз, якщо ми збираємося вставити 12, ми можемо пропустити від 5 до 10, не роблячи всіх інших порівнянь. Ми можемо пропустити їх зі списком пропусків. І нам не потрібно турбуватися про збалансоване дерево - імовірнісний характер укладання робить це для нас.

Чому це так корисно? Тому що, вставляючи 10, я можу це зробити, заблокувавши написання на 5 та 7 та 8 покажчиках, а не на всю структуру. І хоча я це роблю, читачі все ще можуть переглядати список пропусків, не маючи непослідовного стану. Для одночасного використання його швидше не потрібно блокувати. Для ітерації над нижнім шаром його швидше, ніж дерево (радощі алгоритмів BFS та DFS для навігації по дереву - про них не потрібно турбуватися).

Чи зіткнешся ти з цим? Напевно, ви побачите його у використанні місцями. І тоді ви будете знати , чому автор вибрав цю реалізацію , а не TreeMapчи HashMapдля структури.

Значна частина цього була запозичена з моєї публікації в блозі: Пропустити список


Дякую. Я не розумію навіть загальної реалізації; Я бачу їхню схожість з BST. Я спробував продумати, як я це втілю, і думка про управління всіма вказівниками / посиланнями постійно мене бентежила. Можливо, я дозволю собі занадто засмутитися. Спасибі. Я спробую підібрати його завтра, використовуючи вашу відповідь як вихідну точку.
Carcigenicate

2
@Carcigenicate Ви також можете знайти оригінальний документ, представляючи їх корисним - Пропуск списків: ймовірна альтернатива збалансованим деревам . Це досить зрозумілий документ у порівнянні з більшістю наукових праць, який може перевершити голову людей. У таблиці 2 ви побачите їх у використанні. Цей фактор часу для вставки або видалення додає складності інших рішень.

2
Зв'язаний список "просто вироджене дуже неврівноважене дерево". Пропускний список - це часткове додавання назад якоїсь структури дерева вгорі списку. Особисто я великий шанувальник стійких структур даних, і дерева, здається, простіше міркувати саме в цьому конкретному контексті. Я не думаю, що це випадковість, що Clojure, Scala та ін. схоже, що вони сходяться на якусь спробу хеш-стилю в стилі Багвелла, як основна структура даних (Філ Багвелл навіть брав участь у переробці рамок колекцій Scala для Scala 2.8.) Пропуск списків все ще приємний.
Йорг W Міттаг

Це найкраще пояснення того, як працює пропускний список, який я коли-небудь читав.
габоровий
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.