Який найефективніший алгоритм сортування постійного простору?


19

Я шукаю алгоритм сортування для масивів int, який не виділяє байт, окрім розміру масиву, і обмежується двома інструкціями:

  1. SWAP: підміняйте наступний індекс на поточний;

  2. Перемістити: переміщує курсор на +1 або -1 індекс;

Тобто ви не можете поміняти 100місцями не сусідніми індексами, а також не поміняти індекс після того, як ви просто поміняли індекс 10. Який найефективніший алгоритм - тобто той, який використовує меншу кількість загальних ходів?


13
Не дивно, що це фізична машина, яка сортуватиме список візків, наклеєних на розгорнутий довгу стрічку. Машина може переміщувати стрічку лише вперед або назад, а також може обмінятись лише сусідніми картами, з корсом. У реальному світі ти не можеш телепортуватися навколо, тож, це обмеження ...
MaiaVictor

2
Отже, коли ви говорите, що хочете алгоритм, який не виділяє байт, окрім розміру масиву , я думаю, ви посилаєтесь лише на сховище елементів, правда? Я ще можу виділити лічильники і таке?
Darkhogg

5
О, звичайно. Звичайно. Можна виділити деякі додаткові структури. Ви навіть можете виділити весь масив і зробити багато дійсно важких обчислень, і це рахується як 0 вартість. Єдине, що вам потрібно мінімізувати - це кількість SWAP / MOVEs фактичної фізичної машини, оскільки вона повільна. Сорт бульбашки - це найкраще, що я міг придумати, але я здогадався, що повинні бути кращі варіанти.
MaiaVictor

1
Я не думаю, що існує такий алгоритм. Без будь - яких додаткової пам'яті, ви не будете мати спосіб зберігати будь-який стан елемента управління.
Рафаель

1
@svrm: так, тоді з необмеженою оперативною пам’яттю та можливістю копіювати стрічку в оперативну пам’ять і робити довільні обчислення на ній безкоштовно, алгоритм «спробуй все і застосуй найкраще» є оптимальним за кількістю ходів стрічки. Навряд чи це буде практично, але це тому, що на практиці час виконання буде тривалістю років, а не 0 ;-) Якщо коштує N рухів, щоб скопіювати стрічку довжиною N в оперативну пам'ять, то наївна груба сила може бути не оптимальною, але це в межах N оптимального. Але нічого з цього не стосується вашої проблеми: багато проблем, коли заявлено таким чином, можна було б вирішити «офлайн» за допомогою хибного алгоритму.
Стів Джессоп

Відповіді:


13

Розглянемо сорт коктейльного шейкера , який є двонаправленою версією сортування бульбашок. Ви роздуваєте від низького до високого, а потім (це додається частина) ви перепустіть від високого до низького, повторіть до готовності. Це все ще , але це робить значно менше пропусків в середньому, оскільки дрібні елементи біля верхнього кінця масиву будуть переміщені у своє остаточне положення за один прохід, а не через N проходів. Також ви можете відслідковувати найнижчі та найвищі позиції, де відбувся своп; наступні пропуски не потрібно сканувати за межами цих точок.O(n2)


4

Кількість підказок суміжних елементів, необхідних для замовлення масиву, дорівнює кількості інверсій у масиві. Усього з n елементів - максимум n * (n-1) / 2 інверсій, тому сортування бульбашок дає асимптотично оптимальну кількість свопів у цій моделі.


Насправді сортування бульбашок дасть саме оптимальну кількість свопів. Однак для кожної перестановки існує кілька способів зробити оптимальну кількість свопів, і не очевидно, який з них зменшує загальну кількість рухів. (Під сортуванням бульбашок я маю на увазі "вибрати найбільшу несортивну і перемістити її до кінця відсортованої")
Петро Кравчук

4

O(n2)

+

Алгоритм, який не використовує булевий прапор, щоб знати, замінили ми який-небудь елемент чи ні, наведено нижче (хитрість зберігати інформацію в стані машини, а не пам'ять):

Start:
    Do until we are not at the leftmost position (Op 4)
        move left (Op 2b)

Check:
    If we are at rightmost position (Op 3)
        goto Finished:
    If current value is larger than next value (Op 5)
        goto Unfinished:
    move right (Op 2a)
    Repeat Check:

Unfinished:
    If we are at rightmost position (Op 3)
        goto Start:
    If current value is larger than next value (Op 5)
        swap the elements (Op 1) and move right (Op 2a)
    Repeat Unfinished:

Finished:
    The list is sorted now, output it.

Рішення Еріка Ліпперта, сорт gnome також працює, оскільки в основному це двосторонній міхур.


Що з сортуванням вставки?
Darkhogg

Для сортування бульбашок потрібно щонайменше два лічильника циклу, які вже більше, ніж дозволено.
Рафаель

1
Ні, ви можете піти вліво і вправо, а потім вправо вліво, поки не буде змінитись (що є максимально n разів) без використання лічильника. Вам навіть не потрібно додаткового місця для булевого прапора, щоб помітити, чи є зміни. Якщо є зміна, ви просто переходите до іншої підпрограми, яка робить те саме, за винятком іншої підпрограми.
Шрееш

1
І звичайно, я припускаю, що ви можете читати порожні в обох кінцях, щоб ви могли знати, що це початок чи кінець списку. Крім того, я припускаю, що ми читаємо і поточний, і наступний елемент, щоб знати, чи потрібно міняти місцями.
Шрееш

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