Метод Бенті-Сакса дає досить природну стійку чергу пріоритетів.
Зберігайте свої дані в послідовності відсортованих масивів . A i має розмір 2 i . Кожен масив також підтримує лічильник c i . Записи масиву A i [ c i ] , … , A i [ 2 i - 1 ] містять дані.A0,…,AkAi2iciAi[ci],…,Ai[2i−1]
Для кожного , все елементи А я були додані пізніше , ніж в А я + 1 , і в межах кожного A I елементи впорядковані за значенням зі зв'язками порушуються шляхом розміщення старих елементів попереду нових елементів. Зауважте, що це означає, що ми можемо об'єднати A i і A i + 1 і зберегти це впорядкування. (У випадку зв’язків під час злиття візьміть елемент з A i + 1. )iAiAi+1AiAiAi+1Ai+1
Щоб вставити значення , знайдіть найменше i таке, що A i містить 0 елементів, об'єднайте A 0 , … , A i - 1 і x , збережіть це в A i і встановіть c 0 , … , c i відповідним чином.xiAiA0,…,Ai−1xAic0,…,ci
Для витягування min знайдіть найбільший індекс такий, що перший елемент в A i [ c i ] мінімальний за всі i i з приростом c i .iAi[ci]ici
За стандартним аргументу, це дає амортизується час на операцію і стабільно з - за впорядкування описано вище.O(logn)
Для послідовності з вставок та вилучень для цього використовується n записів масиву (не зберігайте порожні масиви) плюс O ( log n ) слів даних бухгалтерії. Це не відповідає версії питання Міхай, але показує, що стійке обмеження не потребує великих витрат на приміщення. Зокрема, це свідчить про відсутність нижньої межі Ω ( n ) на необхідному додатковому просторі.nnO(logn)Ω(n)
Оновлення: Рольф Фагерберг вказує, що якщо ми можемо зберігати нульові (не дані) значення, то всю цю структуру даних можна упакувати в масив розміром , де n - кількість вставок на даний момент.nn
По-перше, зауважте, що ми можемо запакувати у масив у такому порядку ( спочатку A k , а потім A k - 1, якщо він не порожній тощо). Структура цього повністю закодована двійковим поданням n , кількістю елементів, вставлених дотепер. Якщо бінарне подання n має 1 у положенні i , то A i буде займати розташування масиву 2 i , інакше воно не займе жодного місця розташування масиву.Ak,…,A0AkAk−1nniAi2i
Під час вставки, та довжини нашого масиву збільшуємо на 1, і ми можемо об'єднати A 0 , … , A i плюс новий елемент, використовуючи існуючі на місці стабільні алгоритми злиття.nA0,…,Ai
Тепер, де ми використовуємо нульові значення, це позбавлення від лічильників . У A i ми зберігаємо перше значення, за ним - значення c i null, а потім - 2 i - c i - 1 . Під час витягу-хв ми все ще можемо знайти значення для вилучення за час O ( log n ) , дослідивши A 0 [ 0 ] , … , A k [ 0 ] . Коли ми знайдемо це значення в A i [ 0ciAici2i−ci- 1O(logn )A0[ 0 ] , … ,Aк[ 0 ] ми встановлюємо A i [ 0 ] на null, а потім робимо двійковий пошук на A i, щоб знайти перше ненулеве значення A i [ c i ] і підміняти A i [ 0 ] і A i [ c i ] .Аi[ 0 ]Аi[ 0 ]АiАi[ci]Аi[ 0 ]Аi[ci]
Кінцевий результат: Вся структура може бути реалізована за допомогою одного масиву, довжина якого збільшується з кожною вставкою, і одного лічильника, , який підраховує кількість вставок.н