Позитивний результат: наполегливість не надто коштує. Можна показати, що кожну структуру даних можна зробити повністю стійкою з максимум уповільненням.O(lgn)
Доведення: Ви можете взяти масив і зробити його стійким, використовуючи стандартні структури даних (наприклад, збалансоване бінарне дерево; див. Кінець цієї відповіді для більш детальної інформації). При цьому виникає O(lgn) уповільнення : кожен доступ до масиву займає час із стійкою структурою даних, а не O ( 1 ) час для непостійного масиву. Тепер візьміть будь-який імперативний алгоритм, час роботи якого в моделі оперативної пам'яті дорівнює O ( f ( n ) ) , де n позначає об'єм використовуваної пам'яті. Представити всю пам'ять як один великий масив (зO(lgn)O(1)O(f(n))n елементів), і зробіть його стійким, використовуючи стійку карту. Кожен крок імперативного алгоритму має максимум O ( lg n ) уповільнення, тому загальний час роботи O ( f ( n ) lg n ) .nO(lgn)O(f(n)lgn)
Мабуть, можна зробити трохи краще: мабуть, можна зменшити коефіцієнт уповільнення до (очікуваний, амортизований час), використовуючи методи, наведені нижче в документі Demaine, - але я не знайомий з деталями цієї роботи, тому я не можу поручитися за це сам. Завдяки jbapple за це спостереження.O(lglgn)
Негативний результат: у деяких структурах даних ви не можете уникнути деякого уповільнення. Щоб відповісти на ваше третє запитання, існують структури даних, де відомо, що їх наполегливість вносить деяке уповільнення.
Зокрема, розглянемо масив з елементів. Без наполегливості кожен доступ до масиву займаєn (в моделі ОЗУ). З наполегливістю, очевидно, було показано, що немає способу побудувати стійкий масив знайгіршим випадком складності O ( 1 ) для доступу до випадкового елемента. Зокрема, мабуть, нижня межа показує, що повністю стійкі масиви повинні матичас доступу Ω ( lg lg n ) . Ця нижня межа стверджується на п.3 наступного документу:O(1)O(1)Ω(lglgn)
Нижня межа приписується Михайлові Патраску, але немає жодного посилання на джерело, яке б наводило деталі доказу цієї твердженої нижньої межі.
Багата область досліджень. Якщо ми візьмемо довільну структуру даних або алгоритм, це делікатне запитання, чи можна зробити його стійким з максимум уповільнення чи ні. Я не знаю жодної загальної теореми класифікації. Однак існує багато досліджень щодо того, як зробити конкретні структури даних стійкими та ефективними.O(1)
Існує також міцний зв’язок з функціональними мовами програмування. Зокрема, кожна структура даних, яка може бути реалізована суто функціональним способом (без мутацій), - це вже стійка структура даних. (Навпаки, це не обов'язково, на жаль.) Якщо ви хочете косити очі, ви можете сприймати це як деяку слабку різновид теореми часткової класифікації: якщо вона реалізовується в чисто функціональній мові програмування з тими ж межами часу, що і в Імперативна мова, то існує стійка структура даних з тими ж межами часу, що і непостійна. Я усвідомлюю, що це, мабуть, не те, що ви шукали - це здебільшого лише тривіальне переформулювання ситуації.
Як створити стійкий масив. Я не буду намагатися описати конструкцію, як створити повністю стійкий масив з найгіршим часом доступу . Однак основні ідеї не надто складні, тому я підсумую суть ідей.O(lgn)
Основна ідея полягає в тому, що ми можемо прийняти будь-яку структуру даних бінарних дерев і зробити її стійкою за допомогою методики, званої копіювання контуру . Скажімо, у нас є двійкове дерево, і ми хочемо змінити значення в якомусь листі . Однак для наполегливості ми не наважуємось змінювати значення у цьому листі на місці. Натомість ми робимо копію цього аркуша та змінюємо значення в копії. Потім ми робимо копію його батьківського і змінюємо відповідний дочірній вказівник на копію, щоб вказати на новий лист. Продовжуйте таким чином, клонуючи кожен вузол на шляху від кореня до листа. Якщо ми хочемо змінити лист на глибині d , для цього потрібно скопіювати d вузлів.ℓdd
Якщо у нас збалансоване двійкове дерево має вузлів, то всі листя мають глибину O ( lg n ) , тому ця операція над двійковим деревом займаєnO(lgn) . Я пропускаю деякі деталі - щоб досягти O ( lg n ) найгіршого часу, нам може знадобитися перебалансувати дерево, щоб воно залишалося збалансованим - але це дає суть цього.O(lgn)O(lgn)
Більше пояснень із гарними картинками можна знайти на таких ресурсах:
Це дасть вам головну думку. Є додаткові деталі, про які слід подбати, але деталі не входять у це питання. На щастя, це все стандартні речі, і в літературі є багато інформації про те, як будувати такі структури даних. Не соромтеся задавати окреме запитання, якщо вищевказаних ресурсів недостатньо та хочете отримати більше інформації про деталі побудови стійкої структури даних масиву.