Чи можна уникнути кроку "поділу" у вигляді злиття?


13

Об’єднання сортування

Отже сортування злиття - це алгоритм розділення та підкорення. Під час перегляду вищевказаної діаграми я думав, чи можна взагалі обійти всі етапи поділу.

Якщо ви повторили початковий масив під час стрибків на два, ви можете отримати елементи в індексі i та i + 1 і помістити їх у власні відсортовані масиви. Після того як у вас є всі ці підмасиви ([7,14], [3,12], [9,11] та [2,6], як показано на діаграмі), ви можете просто перейти до звичайної процедури злиття, щоб отримати відсортований масив.

Чи ітерація через масив та негайне генерування потрібних підмасивів менш ефективні, ніж виконання етапів поділу в повному обсязі?


Відповіді:


29

Плутанина виникає через різницю між концептуальним описом алгоритму та його реалізацією .

Логічне об'єднання сортування описується як розділення масиву на менші масиви, а потім об'єднання їх назад разом. Однак "розділення масиву" не означає "створення абсолютно нового масиву в пам'яті", або щось подібне - він може бути реалізований в коді як

/*
 * Note: array is now split into  [0..n) and [n..N)
 */

тобто ніякої фактичної роботи не відбувається, а "розщеплення" суто концептуальне. Отже, те, що ви пропонуєте, безумовно, спрацьовує, але логічно, ви все ще "розщеплюєте" масиви - для роботи вам просто не потрібна робота з комп'ютера :-)


4
Особисто мені дуже подобається сортування злиття знизу вгору, оскільки це простіше реалізувати таким чином, щоб уникнути виділення тимчасового буфера на кожному рівні рекурсії. Замість цього ви виділяєте буфер один раз і пінг-понг між ними.
щурячий вирод

Це - розділення обчислювально - неоперативне ... плюс пропозиція щодо ОП - це лише введення еквівалента злиття масивів одного елемента та початок використання злиття з другого кроку, що здається зайвим, оскільки оригінальне злиття працює так само добре. Немає сенсу в цьому оптимізувати. Він лише вводить зайві поняття та логіку.
luk32

@ratchetfreak: Я теж люблю це, але, на жаль, це не рівнозначно згори вниз (принаймні, версія, яку я знаю). Це зробить злиття по-різному, в основному округлюючи до наступної довжини масиву 2, яка, я думаю, може бути навіть трохи повільніше. Чи знаєте ви про версію знизу вгору, яка точно так само зливається, не платячи здоровенних витрат десь ще?
користувач541686

@Mehrdad Єдине справжнє питання - маленький хвіст, який потрібно об'єднати. У гіршому випадку це означає ще один пропуск для об'єднання в один елемент для масивів довжини 1<<n+1. Хоча я впевнений, що ви можете налаштувати речі, щоб занадто маленький хвіст злився в нижній частині проходу.
храповик виродка

@psmears "Вам просто не потрібна робота з комп'ютера для цього" - тому я здогадуюсь, що продуктивність n викликів деякої рекурсивної функції розділення (7 викликів на прикладі діаграми) в основному незначна?
Jimmy_Rustle

11

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

Крім того, ви можете оптимізувати сортування злиття , розділивши масиви, поки вони не досягнуть певного постійного розміру, після чого ви просто сортуєте їх, наприклад, сортування вставок.

В іншому випадку сортування без розбиття масиву неможливо. Насправді суть сорту "Злиття" - це розділення та сортування підрисів, тобто розділення та перемога.

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